Commit af911133 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux into drm-next

Last batch of new stuff for DC. Highlights:
- Fix some memory leaks
- S3 fixes
- Hotplug fixes
- Fix some CX multi-display issues
- MST fixes
- DML updates from the hw team
- Various code cleanups
- Misc bug fixes

* 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux: (155 commits)
  drm/amd/display:: Fix NULL pointer in Raven hotplug
  drm/amd/display: Fix memoryleak during S3 resume.
  drm/amd/display: add hardware_planes_only to list of affected planes
  drm/amd/display: Fix brace style
  drm/amd/display: Remove needless cast in amdgpu_dm_connector_init()
  drm/amd/display: Fix brace style in amdgpu_dm_connector_ddc_get_modes()
  drm/amd/display: Tidy up dm_drm_plane_reset()
  drm/amd/display: Fix indentation in create_eml_sink()
  drm/amd/display: Replace block with strncpy() in fill_audio_info()
  drm/amd/display: Fix brace style in amdgpu_dm_initialize_drm_device()
  drm/amd/display: Simplify handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in dm_handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in amdgpu_dm_update_connector_after_detect()
  drm/amd/display: Fix indentation in dm_resume()
  drm/amd/display: Fix indentation in dm_suspend()
  drm/amd/display: Simplify dm_late_init()
  amdgpu/dc: inline dml_round_to_multiple
  amdgpu/dc: drop dml_util_is_420
  drm/amd/display: Add bunch of missing license headers in DML
  amdgpu/dc: inline a bunch of the dml wrappers.
  ...
parents bd21a37d 9b38bd1b
...@@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA ...@@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA
by default. This includes Polaris, Carrizo, Tonga, Bonaire, by default. This includes Polaris, Carrizo, Tonga, Bonaire,
and Hawaii. and Hawaii.
config DRM_AMD_DC_FBC
bool "AMD FBC - Enable Frame Buffer Compression"
depends on DRM_AMD_DC
help
Choose this option if you want to use frame buffer compression
support.
This is a power optimisation feature, check its availability
on your hardware before enabling this option.
config DRM_AMD_DC_DCN1_0 config DRM_AMD_DC_DCN1_0
bool "DCN 1.0 Raven family" bool "DCN 1.0 Raven family"
depends on DRM_AMD_DC && X86 depends on DRM_AMD_DC && X86
......
...@@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev, ...@@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev,
DM_IRQ_TABLE_LOCK(adev, irq_table_flags); DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
} }
if (handler_in == NULL) { /* Remove ALL handlers. */
/* Remove ALL handlers. */ if (handler_in == NULL)
continue; continue;
}
if (handler_in == handler_temp) { /* Remove a SPECIFIC handler.
/* Remove a SPECIFIC handler. * Found our handler - we can stop here. */
* Found our handler - we can stop here. */ if (handler_in == handler_temp)
break; break;
}
} }
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
if (handler_in != NULL && handler_removed == false) { if (handler_in != NULL && handler_removed == false)
DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n", DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
handler_in); handler_in);
}
} }
static bool static bool
...@@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) ...@@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
* Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK * Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK
* will be disabled from manage_dm_interrupts on disable CRTC. * will be disabled from manage_dm_interrupts on disable CRTC.
*/ */
for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) { for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
...@@ -462,7 +459,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) ...@@ -462,7 +459,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
DRM_DEBUG_KMS("DM_IRQ: early resume\n"); DRM_DEBUG_KMS("DM_IRQ: early resume\n");
/* re-enable short pulse interrupts HW interrupt */ /* re-enable short pulse interrupts HW interrupt */
for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) { for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
...@@ -488,7 +485,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) ...@@ -488,7 +485,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
* Renable HW interrupt for HPD and only since FLIP and VBLANK * Renable HW interrupt for HPD and only since FLIP and VBLANK
* will be enabled from manage_dm_interrupts on enable CRTC. * will be enabled from manage_dm_interrupts on enable CRTC.
*/ */
for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) { for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
......
...@@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { ...@@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
.atomic_get_property = amdgpu_dm_connector_atomic_get_property .atomic_get_property = amdgpu_dm_connector_atomic_get_property
}; };
static int dm_connector_update_modes(struct drm_connector *connector,
struct edid *edid)
{
int ret;
ret = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
return ret;
}
static int dm_dp_mst_get_modes(struct drm_connector *connector) static int dm_dp_mst_get_modes(struct drm_connector *connector)
{ {
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
int ret = 0; int ret = 0;
ret = drm_add_edid_modes(&aconnector->base, aconnector->edid); if (!aconnector)
return dm_connector_update_modes(connector, NULL);
if (!aconnector->edid) {
struct edid *edid;
struct dc_sink *dc_sink;
struct dc_sink_init_data init_params = {
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
drm_edid_to_eld(&aconnector->base, aconnector->edid); if (!edid) {
drm_mode_connector_update_edid_property(
&aconnector->base,
NULL);
return ret;
}
aconnector->edid = edid;
dc_sink = dc_link_add_remote_sink(
aconnector->dc_link,
(uint8_t *)edid,
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
dc_sink->priv = aconnector;
aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink)
amdgpu_dm_add_sink_to_freesync_module(
connector, edid);
drm_mode_connector_update_edid_property(
&aconnector->base, edid);
}
ret = dm_connector_update_modes(connector, aconnector->edid);
return ret; return ret;
} }
...@@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); drm_connector_list_iter_begin(dev, &conn_iter);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector_iter(connector, &conn_iter) {
aconnector = to_amdgpu_dm_connector(connector); aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->mst_port == master if (aconnector->mst_port == master
&& !aconnector->port) { && !aconnector->port) {
...@@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
aconnector->port = port; aconnector->port = port;
drm_mode_connector_set_path_property(connector, pathprop); drm_mode_connector_set_path_property(connector, pathprop);
drm_modeset_unlock(&dev->mode_config.connection_mutex); drm_connector_list_iter_end(&conn_iter);
return &aconnector->base; return &aconnector->base;
} }
} }
drm_modeset_unlock(&dev->mode_config.connection_mutex); drm_connector_list_iter_end(&conn_iter);
aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector) if (!aconnector)
...@@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) ...@@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
{ {
struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
struct drm_device *dev = master->base.dev; struct drm_device *dev = master->base.dev;
struct amdgpu_device *adev = dev->dev_private;
struct drm_connector *connector;
struct amdgpu_dm_connector *aconnector;
struct edid *edid;
struct dc_sink *dc_sink;
drm_modeset_lock_all(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->port &&
aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
!aconnector->dc_sink) {
/*
* This is plug in case, where port has been created but
* sink hasn't been created yet
*/
if (!aconnector->edid) {
struct dc_sink_init_data init_params = {
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
if (!edid) {
drm_mode_connector_update_edid_property(
&aconnector->base,
NULL);
continue;
}
aconnector->edid = edid;
dc_sink = dc_link_add_remote_sink(
aconnector->dc_link,
(uint8_t *)edid,
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
dc_sink->priv = aconnector;
aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink)
amdgpu_dm_add_sink_to_freesync_module(
connector,
edid);
dm_restore_drm_connector_state(connector->dev, connector);
} else
edid = aconnector->edid;
DRM_DEBUG_KMS("edid retrieved %p\n", edid);
drm_mode_connector_update_edid_property( drm_kms_helper_hotplug_event(dev);
&aconnector->base,
aconnector->edid);
}
}
drm_modeset_unlock_all(dev);
schedule_work(&adev->dm.mst_hotplug_work);
} }
static void dm_dp_mst_register_connector(struct drm_connector *connector) static void dm_dp_mst_register_connector(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
int i;
drm_modeset_lock_all(dev);
if (adev->mode_info.rfbdev) {
/*Do not add if already registered in past*/
for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
== connector) {
drm_modeset_unlock_all(dev);
return;
}
}
if (adev->mode_info.rfbdev)
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
}
else else
DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
drm_modeset_unlock_all(dev);
drm_connector_register(connector); drm_connector_register(connector);
} }
......
...@@ -35,6 +35,12 @@ ...@@ -35,6 +35,12 @@
#include "amdgpu_dm_irq.h" #include "amdgpu_dm_irq.h"
#include "amdgpu_pm.h" #include "amdgpu_pm.h"
unsigned long long dm_get_timestamp(struct dc_context *ctx)
{
/* TODO: return actual timestamp */
return 0;
}
bool dm_write_persistent_data(struct dc_context *ctx, bool dm_write_persistent_data(struct dc_context *ctx,
const struct dc_sink *sink, const struct dc_sink *sink,
const char *module_name, const char *module_name,
......
...@@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger, ...@@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger,
logger->buffer_read_offset = 0; logger->buffer_read_offset = 0;
logger->buffer_write_offset = 0; logger->buffer_write_offset = 0;
logger->write_wrap_count = 0;
logger->read_wrap_count = 0;
logger->open_count = 0; logger->open_count = 0;
logger->flags.bits.ENABLE_CONSOLE = 1; logger->flags.bits.ENABLE_CONSOLE = 1;
...@@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry) ...@@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry)
} }
/* Print everything unread existing in log_buffer to debug console*/ /* Print everything unread existing in log_buffer to debug console*/
static void flush_to_debug_console(struct dal_logger *logger) void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
{ {
int i = logger->buffer_read_offset; char *string_start = &logger->log_buffer[logger->buffer_read_offset];
char *string_start = &logger->log_buffer[i];
dm_output_to_console( if (should_warn)
"---------------- FLUSHING LOG BUFFER ----------------\n"); dm_output_to_console(
while (i < logger->buffer_write_offset) { "---------------- FLUSHING LOG BUFFER ----------------\n");
while (logger->buffer_read_offset < logger->buffer_write_offset) {
if (logger->log_buffer[i] == '\0') { if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
dm_output_to_console("%s", string_start); dm_output_to_console("%s", string_start);
string_start = (char *)logger->log_buffer + i + 1; string_start = logger->log_buffer + logger->buffer_read_offset + 1;
} }
i++; logger->buffer_read_offset++;
} }
dm_output_to_console( if (should_warn)
"-------------- END FLUSHING LOG BUFFER --------------\n\n"); dm_output_to_console(
"-------------- END FLUSHING LOG BUFFER --------------\n\n");
} }
static void log_to_internal_buffer(struct log_entry *entry) static void log_to_internal_buffer(struct log_entry *entry)
...@@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry) ...@@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry)
if (size > 0 && size < logger->log_buffer_size) { if (size > 0 && size < logger->log_buffer_size) {
int total_free_space = 0; int buffer_space = logger->log_buffer_size -
int space_before_wrap = 0; logger->buffer_write_offset;
if (logger->buffer_write_offset > logger->buffer_read_offset) { if (logger->buffer_write_offset == logger->buffer_read_offset) {
total_free_space = logger->log_buffer_size -
logger->buffer_write_offset +
logger->buffer_read_offset;
space_before_wrap = logger->log_buffer_size -
logger->buffer_write_offset;
} else if (logger->buffer_write_offset <
logger->buffer_read_offset) {
total_free_space = logger->log_buffer_size -
logger->buffer_read_offset +
logger->buffer_write_offset;
space_before_wrap = total_free_space;
} else if (logger->write_wrap_count !=
logger->read_wrap_count) {
/* Buffer is completely full already */
total_free_space = 0;
space_before_wrap = 0;
} else {
/* Buffer is empty, start writing at beginning */ /* Buffer is empty, start writing at beginning */
total_free_space = logger->log_buffer_size; buffer_space = logger->log_buffer_size;
space_before_wrap = logger->log_buffer_size;
logger->buffer_write_offset = 0; logger->buffer_write_offset = 0;
logger->buffer_read_offset = 0; logger->buffer_read_offset = 0;
} }
if (space_before_wrap > size) { if (buffer_space > size) {
/* No wrap around, copy 'size' bytes /* No wrap around, copy 'size' bytes
* from 'entry->buf' to 'log_buffer' * from 'entry->buf' to 'log_buffer'
*/ */
...@@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry) ...@@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry)
entry->buf, size); entry->buf, size);
logger->buffer_write_offset += size; logger->buffer_write_offset += size;
} else if (total_free_space > size) {
/* We have enough room without flushing,
* but need to wrap around */
int space_after_wrap = total_free_space -
space_before_wrap;
memmove(logger->log_buffer +
logger->buffer_write_offset,
entry->buf, space_before_wrap);
memmove(logger->log_buffer, entry->buf +
space_before_wrap, space_after_wrap);
logger->buffer_write_offset = space_after_wrap;
logger->write_wrap_count++;
} else { } else {
/* Not enough room remaining, we should flush /* Not enough room remaining, we should flush
* existing logs */ * existing logs */
/* Flush existing unread logs to console */ /* Flush existing unread logs to console */
flush_to_debug_console(logger); dm_logger_flush_buffer(logger, true);
/* Start writing to beginning of buffer */ /* Start writing to beginning of buffer */
memmove(logger->log_buffer, entry->buf, size); memmove(logger->log_buffer, entry->buf, size);
...@@ -325,9 +290,10 @@ void dm_logger_write( ...@@ -325,9 +290,10 @@ void dm_logger_write(
log_heading(&entry); log_heading(&entry);
size = dm_log_to_buffer( size = dm_log_to_buffer(
buffer, LOG_MAX_LINE_SIZE, msg, args); buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
entry.buf_offset += size; buffer[entry.buf_offset + size] = '\0';
entry.buf_offset += size + 1;
/* --Flush log_entry buffer-- */ /* --Flush log_entry buffer-- */
/* print to kernel console */ /* print to kernel console */
......
...@@ -26,42 +26,5 @@ ...@@ -26,42 +26,5 @@
#ifndef __DAL_LOGGER_H__ #ifndef __DAL_LOGGER_H__
#define __DAL_LOGGER_H__ #define __DAL_LOGGER_H__
/* Structure for keeping track of offsets, buffer, etc */
#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
* change log line size to 896 to meet the request.
*/
#define LOG_MAX_LINE_SIZE 896
#include "include/logger_types.h"
struct dal_logger {
/* How far into the circular buffer has been read by dsat
* Read offset should never cross write offset. Write \0's to
* read data just to be sure?
*/
uint32_t buffer_read_offset;
/* How far into the circular buffer we have written
* Write offset should never cross read offset
*/
uint32_t buffer_write_offset;
uint32_t write_wrap_count;
uint32_t read_wrap_count;
uint32_t open_count;
char *log_buffer; /* Pointer to malloc'ed buffer */
uint32_t log_buffer_size; /* Size of circular buffer */
uint32_t mask; /*array of masks for major elements*/
union logger_flags flags;
struct dc_context *ctx;
};
#endif /* __DAL_LOGGER_H__ */ #endif /* __DAL_LOGGER_H__ */
...@@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1( ...@@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1(
info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
info->lcd_timing.misc_info.H_REPLICATION_BY2 = info->lcd_timing.misc_info.H_REPLICATION_BY2 =
lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2; !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
info->lcd_timing.misc_info.V_REPLICATION_BY2 = info->lcd_timing.misc_info.V_REPLICATION_BY2 =
lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2; !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
info->lcd_timing.misc_info.COMPOSITE_SYNC = info->lcd_timing.misc_info.COMPOSITE_SYNC =
lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC; !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
info->lcd_timing.misc_info.INTERLACE = info->lcd_timing.misc_info.INTERLACE =
lvds->lcd_timing.miscinfo & ATOM_INTERLACE; !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
/* not provided by VBIOS*/ /* not provided by VBIOS*/
info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
...@@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1( ...@@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1(
info->ss_id = 0; info->ss_id = 0;
info->realtek_eDPToLVDS = info->realtek_eDPToLVDS =
(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0); !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
return BP_RESULT_OK; return BP_RESULT_OK;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare
BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
......
...@@ -25,6 +25,41 @@ ...@@ -25,6 +25,41 @@
#include "dcn_calc_math.h" #include "dcn_calc_math.h"
float dcn_bw_mod(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 - arg1 * ((int) (arg1 / arg2));
}
float dcn_bw_min2(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 < arg2 ? arg1 : arg2;
}
unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_max2(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_floor2(const float arg, const float significance) float dcn_bw_floor2(const float arg, const float significance)
{ {
if (significance == 0) if (significance == 0)
...@@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance) ...@@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance)
return flr + 0.00001 >= arg ? arg : flr + significance; return flr + 0.00001 >= arg ? arg : flr + significance;
} }
float dcn_bw_max3(float v1, float v2, float v3)
{
return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
}
float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
{
return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
}
float dcn_bw_pow(float a, float exp) float dcn_bw_pow(float a, float exp)
{ {
float temp; float temp;
......
...@@ -26,38 +26,14 @@ ...@@ -26,38 +26,14 @@
#ifndef _DCN_CALC_MATH_H_ #ifndef _DCN_CALC_MATH_H_
#define _DCN_CALC_MATH_H_ #define _DCN_CALC_MATH_H_
static inline float dcn_bw_mod(const float arg1, const float arg2) float dcn_bw_mod(const float arg1, const float arg2);
{ float dcn_bw_min2(const float arg1, const float arg2);
return arg1 - arg1 * ((int) (arg1 / arg2)); unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
} float dcn_bw_max2(const float arg1, const float arg2);
static inline float dcn_bw_min2(const float arg1, const float arg2)
{
return arg1 < arg2 ? arg1 : arg2;
}
static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
return arg1 > arg2 ? arg1 : arg2;
}
static inline float dcn_bw_max2(const float arg1, const float arg2)
{
return arg1 > arg2 ? arg1 : arg2;
}
static inline float dcn_bw_max3(float v1, float v2, float v3)
{
return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
}
static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
{
return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
}
float dcn_bw_floor2(const float arg, const float significance); float dcn_bw_floor2(const float arg, const float significance);
float dcn_bw_ceil2(const float arg, const float significance); float dcn_bw_ceil2(const float arg, const float significance);
float dcn_bw_max3(float v1, float v2, float v3);
float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
float dcn_bw_pow(float a, float exp); float dcn_bw_pow(float a, float exp);
float dcn_bw_log(float a, float b); float dcn_bw_log(float a, float b);
......
This diff is collapsed.
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "dce/dce_11_0_enum.h" #include "dce/dce_11_0_enum.h"
#include "dce/dce_11_0_sh_mask.h" #include "dce/dce_11_0_sh_mask.h"
#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK 0x007C /* Copied from atombios.h */
#define LINK_INFO(...) \ #define LINK_INFO(...) \
dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \ dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
__VA_ARGS__) __VA_ARGS__)
...@@ -78,14 +79,15 @@ static void destruct(struct dc_link *link) ...@@ -78,14 +79,15 @@ static void destruct(struct dc_link *link)
dc_sink_release(link->remote_sinks[i]); dc_sink_release(link->remote_sinks[i]);
} }
static struct gpio *get_hpd_gpio(const struct dc_link *link) struct gpio *get_hpd_gpio(struct dc_bios *dcb,
struct graphics_object_id link_id,
struct gpio_service *gpio_service)
{ {
enum bp_result bp_result; enum bp_result bp_result;
struct dc_bios *dcb = link->ctx->dc_bios;
struct graphics_object_hpd_info hpd_info; struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info; struct gpio_pin_info pin_info;
if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK) if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
return NULL; return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb, bp_result = dcb->funcs->get_gpio_pin_info(dcb,
...@@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link) ...@@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link)
} }
return dal_gpio_service_create_irq( return dal_gpio_service_create_irq(
link->ctx->gpio_service, gpio_service,
pin_info.offset, pin_info.offset,
pin_info.mask); pin_info.mask);
} }
...@@ -153,7 +155,7 @@ static bool program_hpd_filter( ...@@ -153,7 +155,7 @@ static bool program_hpd_filter(
} }
/* Obtain HPD handle */ /* Obtain HPD handle */
hpd = get_hpd_gpio(link); hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (!hpd) if (!hpd)
return result; return result;
...@@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type) ...@@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
struct gpio *hpd_pin; struct gpio *hpd_pin;
/* todo: may need to lock gpio access */ /* todo: may need to lock gpio access */
hpd_pin = get_hpd_gpio(link); hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_pin == NULL) if (hpd_pin == NULL)
goto hpd_gpio_failure; goto hpd_gpio_failure;
...@@ -496,6 +498,7 @@ static void detect_dp( ...@@ -496,6 +498,7 @@ static void detect_dp(
} }
if (is_mst_supported(link)) { if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
link->type = dc_connection_mst_branch;
/* /*
* This call will initiate MST topology discovery. Which * This call will initiate MST topology discovery. Which
...@@ -524,12 +527,11 @@ static void detect_dp( ...@@ -524,12 +527,11 @@ static void detect_dp(
if (reason == DETECT_REASON_BOOT) if (reason == DETECT_REASON_BOOT)
boot = true; boot = true;
if (dm_helpers_dp_mst_start_top_mgr( if (!dm_helpers_dp_mst_start_top_mgr(
link->ctx, link->ctx,
link, boot)) { link, boot)) {
link->type = dc_connection_mst_branch;
} else {
/* MST not supported */ /* MST not supported */
link->type = dc_connection_single;
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
} }
} }
...@@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) ...@@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->dpcd_caps.sink_count.bits.SINK_COUNT) if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
link->dpcd_sink_count = link->dpcd_caps.sink_count. link->dpcd_sink_count = link->dpcd_caps.sink_count.
bits.SINK_COUNT; bits.SINK_COUNT;
else else
link->dpcd_sink_count = 1; link->dpcd_sink_count = 1;
dal_ddc_service_set_transaction_type( dal_ddc_service_set_transaction_type(
link->ddc, link->ddc,
...@@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) ...@@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->type == dc_connection_mst_branch) { if (link->type == dc_connection_mst_branch) {
LINK_INFO("link=%d, mst branch is now Disconnected\n", LINK_INFO("link=%d, mst branch is now Disconnected\n",
link->link_index); link->link_index);
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
link->mst_stream_alloc_table.stream_count = 0; link->mst_stream_alloc_table.stream_count = 0;
...@@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line( ...@@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line(
struct gpio *hpd; struct gpio *hpd;
enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN; enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
hpd = get_hpd_gpio(link); hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd) { if (hpd) {
switch (dal_irq_get_source(hpd)) { switch (dal_irq_get_source(hpd)) {
...@@ -940,7 +943,7 @@ static bool construct( ...@@ -940,7 +943,7 @@ static bool construct(
goto create_fail; goto create_fail;
} }
hpd_gpio = get_hpd_gpio(link); hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_gpio != NULL) if (hpd_gpio != NULL)
link->irq_source_hpd = dal_irq_get_source(hpd_gpio); link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
...@@ -1343,7 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx, ...@@ -1343,7 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings)); sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
result = true; result = true;
break; break;
case ENGINE_ID_DIGD:
settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
memmove(settings->reg_settings,
integrated_info->dp3_ext_hdmi_reg_settings,
sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
memmove(settings->reg_settings_6g,
integrated_info->dp3_ext_hdmi_6g_reg_settings,
sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
result = true;
break;
default: default:
break; break;
} }
...@@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) ...@@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
is_over_340mhz = true; is_over_340mhz = true;
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) { unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
if (masked_chip_caps == (0x2 << 2)) {
/* DP159, Retimer settings */ /* DP159, Retimer settings */
eng_id = pipe_ctx->stream_res.stream_enc->id; eng_id = pipe_ctx->stream_res.stream_enc->id;
...@@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) ...@@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
write_i2c_default_retimer_setting(pipe_ctx, write_i2c_default_retimer_setting(pipe_ctx,
is_vga_mode, is_over_340mhz); is_vga_mode, is_over_340mhz);
} }
} else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) { } else if (masked_chip_caps == (0x1 << 2)) {
/* PI3EQX1204, Redriver settings */ /* PI3EQX1204, Redriver settings */
write_i2c_redriver_setting(pipe_ctx, is_over_340mhz); write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
} }
...@@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal) ...@@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
else else
dp_disable_link_phy_mst(link, signal); dp_disable_link_phy_mst(link, signal);
} else } else
link->link_enc->funcs->disable_output(link->link_enc, signal); link->link_enc->funcs->disable_output(link->link_enc, signal, link);
} }
enum dc_status dc_link_validate_mode_timing( enum dc_status dc_link_validate_mode_timing(
...@@ -2319,16 +2335,20 @@ void core_link_enable_stream( ...@@ -2319,16 +2335,20 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
allocate_mst_payload(pipe_ctx); allocate_mst_payload(pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
core_dc->hwss.unblank_stream(pipe_ctx,
&pipe_ctx->stream->sink->link->cur_link_settings);
} }
void core_link_disable_stream(struct pipe_ctx *pipe_ctx) void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
{ {
struct dc *core_dc = pipe_ctx->stream->ctx->dc; struct dc *core_dc = pipe_ctx->stream->ctx->dc;
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx); deallocate_mst_payload(pipe_ctx);
core_dc->hwss.disable_stream(pipe_ctx); core_dc->hwss.disable_stream(pipe_ctx, option);
disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
} }
......
...@@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link) ...@@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link)
dp_retrain_link_dp_test(link, &link_settings, false); dp_retrain_link_dp_test(link, &link_settings, false);
} }
/* TODO hbr2 compliance eye output is unstable
* (toggling on and off) with debugger break
* This caueses intermittent PHY automation failure
* Need to look into the root cause */
static uint8_t force_tps4_for_cp2520 = 1;
static void dp_test_send_phy_test_pattern(struct dc_link *link) static void dp_test_send_phy_test_pattern(struct dc_link *link)
{ {
union phy_test_pattern dpcd_test_pattern; union phy_test_pattern dpcd_test_pattern;
...@@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) ...@@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM; test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
break; break;
case PHY_TEST_PATTERN_CP2520_1: case PHY_TEST_PATTERN_CP2520_1:
test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; /* CP2520 pattern is unstable, temporarily use TPS4 instead */
test_pattern = (force_tps4_for_cp2520 == 1) ?
DP_TEST_PATTERN_TRAINING_PATTERN4 :
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break; break;
case PHY_TEST_PATTERN_CP2520_2: case PHY_TEST_PATTERN_CP2520_2:
test_pattern = DP_TEST_PATTERN_CP2520_2; /* CP2520 pattern is unstable, temporarily use TPS4 instead */
test_pattern = (force_tps4_for_cp2520 == 1) ?
DP_TEST_PATTERN_TRAINING_PATTERN4 :
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break; break;
case PHY_TEST_PATTERN_CP2520_3: case PHY_TEST_PATTERN_CP2520_3:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
......
...@@ -89,12 +89,12 @@ void dp_enable_link_phy( ...@@ -89,12 +89,12 @@ void dp_enable_link_phy(
if (dc_is_dp_sst_signal(signal)) { if (dc_is_dp_sst_signal(signal)) {
if (signal == SIGNAL_TYPE_EDP) { if (signal == SIGNAL_TYPE_EDP) {
link_enc->funcs->power_control(link_enc, true); link->dc->hwss.edp_power_control(link->link_enc, true);
link_enc->funcs->enable_dp_output( link_enc->funcs->enable_dp_output(
link_enc, link_enc,
link_settings, link_settings,
clock_source); clock_source);
link_enc->funcs->backlight_control(link_enc, true); link->dc->hwss.edp_backlight_control(link, true);
} else } else
link_enc->funcs->enable_dp_output( link_enc->funcs->enable_dp_output(
link_enc, link_enc,
...@@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) ...@@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dp_receiver_power_ctrl(link, false); dp_receiver_power_ctrl(link, false);
if (signal == SIGNAL_TYPE_EDP) { if (signal == SIGNAL_TYPE_EDP) {
link->link_enc->funcs->backlight_control(link->link_enc, false); link->dc->hwss.edp_backlight_control(link, false);
edp_receiver_ready_T9(link); edp_receiver_ready_T9(link);
link->link_enc->funcs->disable_output(link->link_enc, signal); link->link_enc->funcs->disable_output(link->link_enc, signal, link);
link->link_enc->funcs->power_control(link->link_enc, false); link->dc->hwss.edp_power_control(link->link_enc, false);
} else } else
link->link_enc->funcs->disable_output(link->link_enc, signal); link->link_enc->funcs->disable_output(link->link_enc, signal, link);
/* Clear current link setting.*/ /* Clear current link setting.*/
memset(&link->cur_link_settings, 0, memset(&link->cur_link_settings, 0,
...@@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link, ...@@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link,
dp_receiver_power_ctrl(link, false); dp_receiver_power_ctrl(link, false);
link->dc->hwss.disable_stream(&pipes[i]); link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
link->link_enc->funcs->disable_output( link->link_enc->funcs->disable_output(
link->link_enc, link->link_enc,
SIGNAL_TYPE_DISPLAY_PORT); SIGNAL_TYPE_DISPLAY_PORT,
link);
/* Clear current link setting. */ /* Clear current link setting. */
memset(&link->cur_link_settings, 0, memset(&link->cur_link_settings, 0,
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "opp.h" #include "opp.h"
#include "timing_generator.h" #include "timing_generator.h"
#include "transform.h" #include "transform.h"
#include "dpp.h"
#include "core_types.h" #include "core_types.h"
#include "set_mode_types.h" #include "set_mode_types.h"
#include "virtual/virtual_stream_encoder.h" #include "virtual/virtual_stream_encoder.h"
...@@ -242,7 +243,10 @@ bool resource_construct( ...@@ -242,7 +243,10 @@ bool resource_construct(
pool->stream_enc_count++; pool->stream_enc_count++;
} }
} }
dc->caps.dynamic_audio = false;
if (pool->audio_count < pool->stream_enc_count) {
dc->caps.dynamic_audio = true;
}
for (i = 0; i < num_virtual_links; i++) { for (i = 0; i < num_virtual_links; i++) {
pool->stream_enc[pool->stream_enc_count] = pool->stream_enc[pool->stream_enc_count] =
virtual_stream_encoder_create( virtual_stream_encoder_create(
...@@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) ...@@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
*/ */
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable; pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable; pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
/* Taps calculations */ /* Taps calculations */
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( if (pipe_ctx->plane_res.xfm != NULL)
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (pipe_ctx->plane_res.dpp != NULL)
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (!res) { if (!res) {
/* Try 24 bpp linebuffer */ /* Try 24 bpp linebuffer */
...@@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) ...@@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
} }
if (res) if (res)
...@@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe( ...@@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe(
memset(pipe_ctx, 0, sizeof(*pipe_ctx)); memset(pipe_ctx, 0, sizeof(*pipe_ctx));
pipe_ctx->stream_res.tg = pool->timing_generators[i]; pipe_ctx->stream_res.tg = pool->timing_generators[i];
pipe_ctx->plane_res.mi = pool->mis[i]; pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.xfm = pool->transforms[i]; pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i]; pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i; pipe_ctx->pipe_idx = i;
...@@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context( ...@@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context(
return false; return false;
} }
/* retain new surfaces */
dc_plane_state_retain(plane_state);
free_pipe = acquire_free_pipe_for_stream(context, pool, stream); free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
#if defined(CONFIG_DRM_AMD_DC_DCN1_0) #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
...@@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context( ...@@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context(
free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
} }
#endif #endif
if (!free_pipe) { if (!free_pipe)
stream_status->plane_states[i] = NULL;
return false; return false;
}
/* retain new surfaces */
dc_plane_state_retain(plane_state);
free_pipe->plane_state = plane_state; free_pipe->plane_state = plane_state;
if (head_pipe != free_pipe) { if (head_pipe != free_pipe) {
...@@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context( ...@@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context(
stream_status->plane_count--; stream_status->plane_count--;
/* Trim back arrays */ /* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
for (i = 0; i < stream_status->plane_count; i++) for (; i < stream_status->plane_count; i++)
stream_status->plane_states[i] = stream_status->plane_states[i + 1]; stream_status->plane_states[i] = stream_status->plane_states[i + 1];
stream_status->plane_states[stream_status->plane_count] = NULL; stream_status->plane_states[stream_status->plane_count] = NULL;
...@@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged( ...@@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged(
return true; return true;
} }
bool dc_is_stream_scaling_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
{
if (old_stream == stream)
return true;
if (old_stream == NULL || stream == NULL)
return false;
if (memcmp(&old_stream->src,
&stream->src,
sizeof(struct rect)) != 0)
return false;
if (memcmp(&old_stream->dst,
&stream->dst,
sizeof(struct rect)) != 0)
return false;
return true;
}
/* Maximum TMDS single link pixel clock 165MHz */ /* Maximum TMDS single link pixel clock 165MHz */
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
...@@ -1330,7 +1364,7 @@ static void update_stream_engine_usage( ...@@ -1330,7 +1364,7 @@ static void update_stream_engine_usage(
} }
/* TODO: release audio object */ /* TODO: release audio object */
static void update_audio_usage( void update_audio_usage(
struct resource_context *res_ctx, struct resource_context *res_ctx,
const struct resource_pool *pool, const struct resource_pool *pool,
struct audio *audio, struct audio *audio,
...@@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe( ...@@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe(
pipe_ctx->stream_res.tg = pool->timing_generators[i]; pipe_ctx->stream_res.tg = pool->timing_generators[i];
pipe_ctx->plane_res.mi = pool->mis[i]; pipe_ctx->plane_res.mi = pool->mis[i];
pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.xfm = pool->transforms[i]; pipe_ctx->plane_res.xfm = pool->transforms[i];
pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i]; pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i; pipe_ctx->pipe_idx = i;
...@@ -1414,12 +1450,17 @@ static struct audio *find_first_free_audio( ...@@ -1414,12 +1450,17 @@ static struct audio *find_first_free_audio(
const struct resource_pool *pool) const struct resource_pool *pool)
{ {
int i; int i;
for (i = 0; i < pool->audio_count; i++) {
if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
return pool->audios[i];
}
}
/*not found the matching one, first come first serve*/
for (i = 0; i < pool->audio_count; i++) { for (i = 0; i < pool->audio_count; i++) {
if (res_ctx->is_audio_acquired[i] == false) { if (res_ctx->is_audio_acquired[i] == false) {
return pool->audios[i]; return pool->audios[i];
} }
} }
return 0; return 0;
} }
...@@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged( ...@@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged(
return false; return false;
} }
bool dc_add_stream_to_ctx( enum dc_status dc_add_stream_to_ctx(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx, struct dc_state *new_ctx,
struct dc_stream_state *stream) struct dc_stream_state *stream)
...@@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx( ...@@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx(
if (res != DC_OK) if (res != DC_OK)
DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res); DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res);
return res == DC_OK; return res;
} }
bool dc_remove_stream_from_ctx( enum dc_status dc_remove_stream_from_ctx(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx, struct dc_state *new_ctx,
struct dc_stream_state *stream) struct dc_stream_state *stream)
...@@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources( ...@@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources(
/* acquire new resources */ /* acquire new resources */
pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
#if defined(CONFIG_DRM_AMD_DC_DCN1_0) #ifdef CONFIG_DRM_AMD_DC_DCN1_0
if (pipe_idx < 0) if (pipe_idx < 0)
acquire_first_split_pipe(&context->res_ctx, pool, stream); pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
#endif #endif
if (pipe_idx < 0) if (pipe_idx < 0)
return DC_NO_CONTROLLER_RESOURCE; return DC_NO_CONTROLLER_RESOURCE;
...@@ -1716,17 +1758,18 @@ void dc_resource_state_construct( ...@@ -1716,17 +1758,18 @@ void dc_resource_state_construct(
dst_ctx->dis_clk = dc->res_pool->display_clock; dst_ctx->dis_clk = dc->res_pool->display_clock;
} }
bool dc_validate_global_state( enum dc_status dc_validate_global_state(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx) struct dc_state *new_ctx)
{ {
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
int i, j; int i, j;
if (dc->res_pool->funcs->validate_global && if (dc->res_pool->funcs->validate_global) {
dc->res_pool->funcs->validate_global( result = dc->res_pool->funcs->validate_global(dc, new_ctx);
dc, new_ctx) != DC_OK) if (result != DC_OK)
return false; return result;
}
for (i = 0; new_ctx && i < new_ctx->stream_count; i++) { for (i = 0; new_ctx && i < new_ctx->stream_count; i++) {
struct dc_stream_state *stream = new_ctx->streams[i]; struct dc_stream_state *stream = new_ctx->streams[i];
...@@ -2713,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, ...@@ -2713,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
fmt_bit_depth->pixel_encoding = pixel_encoding; fmt_bit_depth->pixel_encoding = pixel_encoding;
} }
bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
{ {
struct dc *core_dc = dc; struct dc *core_dc = dc;
struct dc_link *link = stream->sink->link; struct dc_link *link = stream->sink->link;
...@@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) ...@@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
link, link,
&stream->timing); &stream->timing);
return res == DC_OK; return res;
} }
bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
{ {
struct dc *core_dc = dc; enum dc_status res = DC_OK;
/* TODO For now validates pixel format only */ /* TODO For now validates pixel format only */
if (core_dc->res_pool->funcs->validate_plane) if (dc->res_pool->funcs->validate_plane)
return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK; return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
return true; return res;
} }
...@@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status( ...@@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status(
* Update the cursor attributes and set cursor surface address * Update the cursor attributes and set cursor surface address
*/ */
bool dc_stream_set_cursor_attributes( bool dc_stream_set_cursor_attributes(
const struct dc_stream_state *stream, struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes) const struct dc_cursor_attributes *attributes)
{ {
int i; int i;
...@@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes( ...@@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes(
return false; return false;
} }
if (attributes->address.quad_part == 0) {
dm_output_to_console("DC: Cursor address is 0!\n");
return false;
}
core_dc = stream->ctx->dc; core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx; res_ctx = &core_dc->current_state->res_ctx;
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp) if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue; continue;
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
continue; continue;
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
pipe_ctx->plane_res.ipp, attributes); if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
pipe_ctx->plane_res.ipp, attributes);
if (pipe_ctx->plane_res.hubp != NULL &&
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
pipe_ctx->plane_res.hubp, attributes);
if (pipe_ctx->plane_res.mi != NULL &&
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
pipe_ctx->plane_res.mi, attributes);
if (pipe_ctx->plane_res.xfm != NULL &&
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
pipe_ctx->plane_res.xfm, attributes);
if (pipe_ctx->plane_res.dpp != NULL &&
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
pipe_ctx->plane_res.dpp, attributes);
} }
stream->cursor_attributes = *attributes;
return true; return true;
} }
...@@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position( ...@@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position(
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
struct mem_input *mi = pipe_ctx->plane_res.mi;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct transform *xfm = pipe_ctx->plane_res.xfm;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_cursor_position pos_cpy = *position; struct dc_cursor_position pos_cpy = *position;
struct dc_cursor_mi_param param = { struct dc_cursor_mi_param param = {
.pixel_clk_khz = stream->timing.pix_clk_khz, .pixel_clk_khz = stream->timing.pix_clk_khz,
...@@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position( ...@@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position(
}; };
if (pipe_ctx->stream != stream || if (pipe_ctx->stream != stream ||
!pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state) (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
!pipe_ctx->plane_state ||
(!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue; continue;
if (pipe_ctx->plane_state->address.type if (pipe_ctx->plane_state->address.type
...@@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position( ...@@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position(
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
pos_cpy.enable = false; pos_cpy.enable = false;
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
if (ipp->funcs->ipp_cursor_set_position != NULL)
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
if (mi != NULL && mi->funcs->set_cursor_position != NULL)
mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
if (hubp != NULL && hubp->funcs->set_cursor_position != NULL)
hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
if (xfm != NULL && xfm->funcs->set_cursor_position != NULL)
xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, hubp->curs_attr.width);
if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
} }
return true; return true;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
/* DC core (private) */ /* DC core (private) */
#include "core_types.h" #include "core_types.h"
#include "transform.h" #include "transform.h"
#include "dpp.h"
/******************************************************************************* /*******************************************************************************
* Private functions * Private functions
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include "inc/compressor.h" #include "inc/compressor.h"
#include "dml/display_mode_lib.h" #include "dml/display_mode_lib.h"
#define DC_VER "3.1.01" #define DC_VER "3.1.07"
#define MAX_SURFACES 3 #define MAX_SURFACES 3
#define MAX_STREAMS 6 #define MAX_STREAMS 6
...@@ -56,11 +56,12 @@ struct dc_caps { ...@@ -56,11 +56,12 @@ struct dc_caps {
uint32_t max_planes; uint32_t max_planes;
uint32_t max_downscale_ratio; uint32_t max_downscale_ratio;
uint32_t i2c_speed_in_khz; uint32_t i2c_speed_in_khz;
unsigned int max_cursor_size; unsigned int max_cursor_size;
unsigned int max_video_width;
bool dcc_const_color;
bool dynamic_audio;
}; };
struct dc_dcc_surface_param { struct dc_dcc_surface_param {
struct dc_size surface_size; struct dc_size surface_size;
enum surface_pixel_format format; enum surface_pixel_format format;
...@@ -132,6 +133,10 @@ struct dc_stream_state_funcs { ...@@ -132,6 +133,10 @@ struct dc_stream_state_funcs {
void (*set_dither_option)(struct dc_stream_state *stream, void (*set_dither_option)(struct dc_stream_state *stream,
enum dc_dither_option option); enum dc_dither_option option);
void (*set_dpms)(struct dc *dc,
struct dc_stream_state *stream,
bool dpms_off);
}; };
struct link_training_settings; struct link_training_settings;
...@@ -162,6 +167,23 @@ struct dc_config { ...@@ -162,6 +167,23 @@ struct dc_config {
bool disable_disp_pll_sharing; bool disable_disp_pll_sharing;
}; };
enum dcc_option {
DCC_ENABLE = 0,
DCC_DISABLE = 1,
DCC_HALF_REQ_DISALBE = 2,
};
enum pipe_split_policy {
MPC_SPLIT_DYNAMIC = 0,
MPC_SPLIT_AVOID = 1,
MPC_SPLIT_AVOID_MULT_DISP = 2,
};
enum wm_report_mode {
WM_REPORT_DEFAULT = 0,
WM_REPORT_OVERRIDE = 1,
};
struct dc_debug { struct dc_debug {
bool surface_visual_confirm; bool surface_visual_confirm;
bool sanity_checks; bool sanity_checks;
...@@ -170,14 +192,21 @@ struct dc_debug { ...@@ -170,14 +192,21 @@ struct dc_debug {
bool timing_trace; bool timing_trace;
bool clock_trace; bool clock_trace;
bool validation_trace; bool validation_trace;
/* stutter efficiency related */
bool disable_stutter; bool disable_stutter;
bool disable_dcc; bool use_max_lb;
enum dcc_option disable_dcc;
enum pipe_split_policy pipe_split_policy;
bool force_single_disp_pipe_split;
bool voltage_align_fclk;
bool disable_dfs_bypass; bool disable_dfs_bypass;
bool disable_dpp_power_gate; bool disable_dpp_power_gate;
bool disable_hubp_power_gate; bool disable_hubp_power_gate;
bool disable_pplib_wm_range; bool disable_pplib_wm_range;
bool use_dml_wm; enum wm_report_mode pplib_wm_report_mode;
bool disable_pipe_split; unsigned int min_disp_clk_khz;
int sr_exit_time_dpm0_ns; int sr_exit_time_dpm0_ns;
int sr_enter_plus_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns;
int sr_exit_time_ns; int sr_exit_time_ns;
...@@ -191,6 +220,11 @@ struct dc_debug { ...@@ -191,6 +220,11 @@ struct dc_debug {
bool disable_dmcu; bool disable_dmcu;
bool disable_psr; bool disable_psr;
bool force_abm_enable; bool force_abm_enable;
bool disable_hbup_pg;
bool disable_dpp_pg;
bool disable_stereo_support;
bool vsr_support;
bool performance_trace;
}; };
struct dc_state; struct dc_state;
struct resource_pool; struct resource_pool;
...@@ -233,7 +267,7 @@ struct dc { ...@@ -233,7 +267,7 @@ struct dc {
struct dm_pp_display_configuration prev_display_config; struct dm_pp_display_configuration prev_display_config;
/* FBC compressor */ /* FBC compressor */
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
struct compressor *fbc_compressor; struct compressor *fbc_compressor;
#endif #endif
}; };
...@@ -268,7 +302,7 @@ struct dc_init_data { ...@@ -268,7 +302,7 @@ struct dc_init_data {
struct dc_config flags; struct dc_config flags;
uint32_t log_mask; uint32_t log_mask;
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr; uint64_t fbc_gpu_addr;
#endif #endif
}; };
...@@ -285,6 +319,38 @@ enum { ...@@ -285,6 +319,38 @@ enum {
TRANSFER_FUNC_POINTS = 1025 TRANSFER_FUNC_POINTS = 1025
}; };
// Moved here from color module for linux
enum color_transfer_func {
transfer_func_unknown,
transfer_func_srgb,
transfer_func_bt709,
transfer_func_pq2084,
transfer_func_pq2084_interim,
transfer_func_linear_0_1,
transfer_func_linear_0_125,
transfer_func_dolbyvision,
transfer_func_gamma_22,
transfer_func_gamma_26
};
enum color_color_space {
color_space_unsupported,
color_space_srgb,
color_space_bt601,
color_space_bt709,
color_space_xv_ycc_bt601,
color_space_xv_ycc_bt709,
color_space_xr_rgb,
color_space_bt2020,
color_space_adobe,
color_space_dci_p3,
color_space_sc_rgb_ms_ref,
color_space_display_native,
color_space_app_ctrl,
color_space_dolby_vision,
color_space_custom_coordinates
};
struct dc_hdr_static_metadata { struct dc_hdr_static_metadata {
/* display chromaticities and white point in units of 0.00001 */ /* display chromaticities and white point in units of 0.00001 */
unsigned int chromaticity_green_x; unsigned int chromaticity_green_x;
...@@ -365,6 +431,12 @@ struct dc_plane_state { ...@@ -365,6 +431,12 @@ struct dc_plane_state {
struct dc_gamma *gamma_correction; struct dc_gamma *gamma_correction;
struct dc_transfer_func *in_transfer_func; struct dc_transfer_func *in_transfer_func;
// sourceContentAttribute cache
bool is_source_input_valid;
struct dc_hdr_static_metadata source_input_mastering_info;
enum color_color_space source_input_color_space;
enum color_transfer_func source_input_tf;
enum dc_color_space color_space; enum dc_color_space color_space;
enum surface_pixel_format format; enum surface_pixel_format format;
enum dc_rotation_angle rotation; enum dc_rotation_angle rotation;
...@@ -449,23 +521,6 @@ struct dc_flip_addrs { ...@@ -449,23 +521,6 @@ struct dc_flip_addrs {
/* TODO: add flip duration for FreeSync */ /* TODO: add flip duration for FreeSync */
}; };
/*
* Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read.
* Any flip related attribute changes must be done through this interface.
*
* After this call:
* Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed.
*/
bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
struct dc_stream_state *stream);
bool dc_post_update_surfaces_to_stream( bool dc_post_update_surfaces_to_stream(
struct dc *dc); struct dc *dc);
...@@ -554,9 +609,12 @@ struct dc_stream_state { ...@@ -554,9 +609,12 @@ struct dc_stream_state {
int phy_pix_clk; int phy_pix_clk;
enum signal_type signal; enum signal_type signal;
bool dpms_off;
struct dc_stream_status status; struct dc_stream_status status;
struct dc_cursor_attributes cursor_attributes;
/* from stream struct */ /* from stream struct */
struct kref refcount; struct kref refcount;
}; };
...@@ -569,11 +627,10 @@ struct dc_stream_update { ...@@ -569,11 +627,10 @@ struct dc_stream_update {
bool dc_is_stream_unchanged( bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream); struct dc_stream_state *old_stream, struct dc_stream_state *stream);
bool dc_is_stream_scaling_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
/* /*
* Setup stream attributes if no stream updates are provided
* there will be no impact on the stream parameters
*
* Set up surface attributes and associate to a stream * Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream. * The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read. * If no surfaces are provided, the stream will be blanked; no memory read.
...@@ -582,14 +639,22 @@ bool dc_is_stream_unchanged( ...@@ -582,14 +639,22 @@ bool dc_is_stream_unchanged(
* After this call: * After this call:
* Surfaces attributes are programmed and configured to be composed into stream. * Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed. * This does not trigger a flip. No surface address is programmed.
*
*/ */
void dc_update_planes_and_stream(struct dc *dc, bool dc_commit_planes_to_stream(
struct dc_surface_update *surface_updates, int surface_count, struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
struct dc_stream_state *dc_stream, struct dc_stream_state *dc_stream,
struct dc_stream_update *stream_update); struct dc_state *state);
void dc_commit_updates_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
struct dc_stream_state *stream,
struct dc_stream_update *stream_update,
struct dc_plane_state **plane_states,
struct dc_state *state);
/* /*
* Log the current stream state. * Log the current stream state.
*/ */
...@@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, ...@@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
uint32_t *h_position, uint32_t *h_position,
uint32_t *v_position); uint32_t *v_position);
bool dc_add_stream_to_ctx( enum dc_status dc_add_stream_to_ctx(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx, struct dc_state *new_ctx,
struct dc_stream_state *stream); struct dc_stream_state *stream);
bool dc_remove_stream_from_ctx( enum dc_status dc_remove_stream_from_ctx(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx, struct dc_state *new_ctx,
struct dc_stream_state *stream); struct dc_stream_state *stream);
...@@ -660,11 +725,11 @@ struct dc_validation_set { ...@@ -660,11 +725,11 @@ struct dc_validation_set {
uint8_t plane_count; uint8_t plane_count;
}; };
bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
bool dc_validate_global_state( enum dc_status dc_validate_global_state(
struct dc *dc, struct dc *dc,
struct dc_state *new_ctx); struct dc_state *new_ctx);
...@@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params); ...@@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
******************************************************************************/ ******************************************************************************/
/* TODO: Deprecated once we switch to dc_set_cursor_position */ /* TODO: Deprecated once we switch to dc_set_cursor_position */
bool dc_stream_set_cursor_attributes( bool dc_stream_set_cursor_attributes(
const struct dc_stream_state *stream, struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes); const struct dc_cursor_attributes *attributes);
bool dc_stream_set_cursor_position( bool dc_stream_set_cursor_position(
......
...@@ -204,6 +204,8 @@ enum surface_pixel_format { ...@@ -204,6 +204,8 @@ enum surface_pixel_format {
/*grow 444 video here if necessary */ /*grow 444 video here if necessary */
}; };
/* Pixel format */ /* Pixel format */
enum pixel_format { enum pixel_format {
/*graph*/ /*graph*/
......
...@@ -92,7 +92,7 @@ struct dc_context { ...@@ -92,7 +92,7 @@ struct dc_context {
bool created_bios; bool created_bios;
struct gpio_service *gpio_service; struct gpio_service *gpio_service;
struct i2caux *i2caux; struct i2caux *i2caux;
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr; uint64_t fbc_gpu_addr;
#endif #endif
}; };
...@@ -151,6 +151,7 @@ enum dc_edid_status { ...@@ -151,6 +151,7 @@ enum dc_edid_status {
EDID_BAD_INPUT, EDID_BAD_INPUT,
EDID_NO_RESPONSE, EDID_NO_RESPONSE,
EDID_BAD_CHECKSUM, EDID_BAD_CHECKSUM,
EDID_THE_SAME,
}; };
/* audio capability from EDID*/ /* audio capability from EDID*/
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define CTX \ #define CTX \
ipp_dce->base.ctx ipp_dce->base.ctx
static void dce_ipp_cursor_set_position( static void dce_ipp_cursor_set_position(
struct input_pixel_processor *ipp, struct input_pixel_processor *ipp,
const struct dc_cursor_position *position, const struct dc_cursor_position *position,
...@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes( ...@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false); REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
} }
static void dce_ipp_program_prescale( static void dce_ipp_program_prescale(
struct input_pixel_processor *ipp, struct input_pixel_processor *ipp,
struct ipp_prescale_params *params) struct ipp_prescale_params *params)
......
...@@ -82,13 +82,6 @@ ...@@ -82,13 +82,6 @@
#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
/* all values are in milliseconds */
/* For eDP, after power-up/power/down,
* 300/500 msec max. delay from LCDVCC to black video generation */
#define PANEL_POWER_UP_TIMEOUT 300
#define PANEL_POWER_DOWN_TIMEOUT 500
#define HPD_CHECK_INTERVAL 10
/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
#define TMDS_MIN_PIXEL_CLOCK 25000 #define TMDS_MIN_PIXEL_CLOCK 25000
/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
...@@ -122,8 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { ...@@ -122,8 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
.psr_program_dp_dphy_fast_training = .psr_program_dp_dphy_fast_training =
dce110_psr_program_dp_dphy_fast_training, dce110_psr_program_dp_dphy_fast_training,
.psr_program_secondary_packet = dce110_psr_program_secondary_packet, .psr_program_secondary_packet = dce110_psr_program_secondary_packet,
.backlight_control = dce110_link_encoder_edp_backlight_control,
.power_control = dce110_link_encoder_edp_power_control,
.connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
.enable_hpd = dce110_link_encoder_enable_hpd, .enable_hpd = dce110_link_encoder_enable_hpd,
.disable_hpd = dce110_link_encoder_disable_hpd, .disable_hpd = dce110_link_encoder_disable_hpd,
...@@ -493,165 +484,6 @@ static void configure_encoder( ...@@ -493,165 +484,6 @@ static void configure_encoder(
REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1); REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
} }
static bool is_panel_powered_on(struct dce110_link_encoder *enc110)
{
bool ret;
uint32_t value;
REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
ret = value;
return ret == 1;
}
/* TODO duplicate of dc_link.c version */
static struct gpio *get_hpd_gpio(const struct link_encoder *enc)
{
enum bp_result bp_result;
struct dc_bios *dcb = enc->ctx->dc_bios;
struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info;
if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK)
return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb,
hpd_info.hpd_int_gpio_uid, &pin_info);
if (bp_result != BP_RESULT_OK) {
ASSERT(bp_result == BP_RESULT_NORECORD);
return NULL;
}
return dal_gpio_service_create_irq(
enc->ctx->gpio_service,
pin_info.offset,
pin_info.mask);
}
/*
* @brief
* eDP only.
*/
static void link_encoder_edp_wait_for_hpd_ready(
struct dce110_link_encoder *enc110,
bool power_up)
{
struct dc_context *ctx = enc110->base.ctx;
struct graphics_object_id connector = enc110->base.connector;
struct gpio *hpd;
bool edp_hpd_high = false;
uint32_t time_elapsed = 0;
uint32_t timeout = power_up ?
PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
if (dal_graphics_object_id_get_connector_id(connector) !=
CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (!power_up)
/* from KV, we will not HPD low after turning off VCC -
* instead, we will check the SW timer in power_up(). */
return;
/* when we power on/off the eDP panel,
* we need to wait until SENSE bit is high/low */
/* obtain HPD */
/* TODO what to do with this? */
hpd = get_hpd_gpio(&enc110->base);
if (!hpd) {
BREAK_TO_DEBUGGER();
return;
}
dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
/* wait until timeout or panel detected */
do {
uint32_t detected = 0;
dal_gpio_get_value(hpd, &detected);
if (!(detected ^ power_up)) {
edp_hpd_high = true;
break;
}
msleep(HPD_CHECK_INTERVAL);
time_elapsed += HPD_CHECK_INTERVAL;
} while (time_elapsed < timeout);
dal_gpio_close(hpd);
dal_gpio_destroy_irq(&hpd);
if (false == edp_hpd_high) {
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: wait timed out!\n", __func__);
}
}
/*
* @brief
* eDP only. Control the power of the eDP panel.
*/
void dce110_link_encoder_edp_power_control(
struct link_encoder *enc,
bool power_up)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
struct bp_transmitter_control cntl = { 0 };
enum bp_result bp_result;
if (dal_graphics_object_id_get_connector_id(enc110->base.connector) !=
CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if ((power_up && !is_panel_powered_on(enc110)) ||
(!power_up && is_panel_powered_on(enc110))) {
/* Send VBIOS command to prompt eDP panel power */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
cntl.action = power_up ?
TRANSMITTER_CONTROL_POWER_ON :
TRANSMITTER_CONTROL_POWER_OFF;
cntl.transmitter = enc110->base.transmitter;
cntl.connector_obj_id = enc110->base.connector;
cntl.coherent = false;
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = enc110->base.hpd_source;
bp_result = link_transmitter_control(enc110, &cntl);
if (BP_RESULT_OK != bp_result) {
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: Panel Power bp_result: %d\n",
__func__, bp_result);
}
} else {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Skipping Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
}
link_encoder_edp_wait_for_hpd_ready(enc110, true);
}
static void aux_initialize( static void aux_initialize(
struct dce110_link_encoder *enc110) struct dce110_link_encoder *enc110)
{ {
...@@ -674,16 +506,6 @@ static void aux_initialize( ...@@ -674,16 +506,6 @@ static void aux_initialize(
} }
/*todo: cloned in stream enc, fix*/
static bool is_panel_backlight_on(struct dce110_link_encoder *enc110)
{
uint32_t value;
REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
return value;
}
void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc, void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
bool exit_link_training_required) bool exit_link_training_required)
{ {
...@@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc, ...@@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
DP_SEC_GSP0_PRIORITY, 1); DP_SEC_GSP0_PRIORITY, 1);
} }
/*todo: cloned in stream enc, fix*/
/*
* @brief
* eDP only. Control the backlight of the eDP panel
*/
void dce110_link_encoder_edp_backlight_control(
struct link_encoder *enc,
bool enable)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
struct bp_transmitter_control cntl = { 0 };
if (dal_graphics_object_id_get_connector_id(enc110->base.connector)
!= CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (enable && is_panel_backlight_on(enc110)) {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: panel already powered up. Do nothing.\n",
__func__);
return;
}
if (!enable && !is_panel_backlight_on(enc110)) {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: panel already powered down. Do nothing.\n",
__func__);
return;
}
/* Send VBIOS command to control eDP panel backlight */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: backlight action: %s\n",
__func__, (enable ? "On":"Off"));
cntl.action = enable ?
TRANSMITTER_CONTROL_BACKLIGHT_ON :
TRANSMITTER_CONTROL_BACKLIGHT_OFF;
/*cntl.engine_id = ctx->engine;*/
cntl.transmitter = enc110->base.transmitter;
cntl.connector_obj_id = enc110->base.connector;
/*todo: unhardcode*/
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = enc110->base.hpd_source;
/* For eDP, the following delays might need to be considered
* after link training completed:
* idle period - min. accounts for required BS-Idle pattern,
* max. allows for source frame synchronization);
* 50 msec max. delay from valid video data from source
* to video on dislpay or backlight enable.
*
* Disable the delay for now.
* Enable it in the future if necessary.
*/
/* dc_service_sleep_in_milliseconds(50); */
link_transmitter_control(enc110, &cntl);
}
static bool is_dig_enabled(const struct dce110_link_encoder *enc110) static bool is_dig_enabled(const struct dce110_link_encoder *enc110)
{ {
uint32_t value; uint32_t value;
...@@ -998,11 +757,6 @@ void dce110_link_encoder_construct( ...@@ -998,11 +757,6 @@ void dce110_link_encoder_construct(
enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
} }
dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX,
"Using channel: %s [%d]\n",
DECODE_CHANNEL_ID(init_data->channel),
init_data->channel);
/* Override features with DCE-specific values */ /* Override features with DCE-specific values */
if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
enc110->base.ctx->dc_bios, enc110->base.id, enc110->base.ctx->dc_bios, enc110->base.id,
...@@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init( ...@@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init(
ASSERT(result == BP_RESULT_OK); ASSERT(result == BP_RESULT_OK);
} else if (enc110->base.connector.id == CONNECTOR_ID_EDP) { } else if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
enc->funcs->power_control(&enc110->base, true); ctx->dc->hwss.edp_power_control(enc, true);
} }
aux_initialize(enc110); aux_initialize(enc110);
...@@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output( ...@@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output(
*/ */
void dce110_link_encoder_disable_output( void dce110_link_encoder_disable_output(
struct link_encoder *enc, struct link_encoder *enc,
enum signal_type signal) enum signal_type signal,
struct dc_link *link)
{ {
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx; struct dc_context *ctx = enc110->base.ctx;
...@@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output( ...@@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output(
return; return;
} }
if (enc110->base.connector.id == CONNECTOR_ID_EDP) if (enc110->base.connector.id == CONNECTOR_ID_EDP)
dce110_link_encoder_edp_backlight_control(enc, false); ctx->dc->hwss.edp_backlight_control(link, false);
/* Power-down RX and disable GPU PHY should be paired. /* Power-down RX and disable GPU PHY should be paired.
* Disabling PHY without powering down RX may cause * Disabling PHY without powering down RX may cause
* symbol lock loss, on which we will get DP Sink interrupt. */ * symbol lock loss, on which we will get DP Sink interrupt. */
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
SRI(DC_HPD_CONTROL, HPD, id) SRI(DC_HPD_CONTROL, HPD, id)
#define LE_COMMON_REG_LIST_BASE(id) \ #define LE_COMMON_REG_LIST_BASE(id) \
SR(LVTMA_PWRSEQ_CNTL), \
SR(LVTMA_PWRSEQ_STATE), \
SR(DMCU_RAM_ACCESS_CTRL), \ SR(DMCU_RAM_ACCESS_CTRL), \
SR(DMCU_IRAM_RD_CTRL), \ SR(DMCU_IRAM_RD_CTRL), \
SR(DMCU_IRAM_RD_DATA), \ SR(DMCU_IRAM_RD_DATA), \
...@@ -104,8 +102,7 @@ ...@@ -104,8 +102,7 @@
LE_COMMON_REG_LIST_BASE(id), \ LE_COMMON_REG_LIST_BASE(id), \
SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
SR(DMU_MEM_PWR_CNTL)
struct dce110_link_enc_aux_registers { struct dce110_link_enc_aux_registers {
uint32_t AUX_CONTROL; uint32_t AUX_CONTROL;
...@@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers { ...@@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers {
}; };
struct dce110_link_enc_registers { struct dce110_link_enc_registers {
/* Backlight registers */
uint32_t LVTMA_PWRSEQ_CNTL;
uint32_t LVTMA_PWRSEQ_STATE;
/* DMCU registers */ /* DMCU registers */
uint32_t MASTER_COMM_DATA_REG1; uint32_t MASTER_COMM_DATA_REG1;
uint32_t MASTER_COMM_DATA_REG2; uint32_t MASTER_COMM_DATA_REG2;
...@@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output( ...@@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output(
/* disable PHY output */ /* disable PHY output */
void dce110_link_encoder_disable_output( void dce110_link_encoder_disable_output(
struct link_encoder *link_enc, struct link_encoder *link_enc,
enum signal_type signal); enum signal_type signal,
struct dc_link *link);
/* set DP lane settings */ /* set DP lane settings */
void dce110_link_encoder_dp_set_lane_settings( void dce110_link_encoder_dp_set_lane_settings(
...@@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( ...@@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table(
struct link_encoder *enc, struct link_encoder *enc,
const struct link_mst_stream_allocation_table *table); const struct link_mst_stream_allocation_table *table);
void dce110_link_encoder_edp_backlight_control(
struct link_encoder *enc,
bool enable);
void dce110_link_encoder_edp_power_control(
struct link_encoder *enc,
bool power_up);
void dce110_link_encoder_connect_dig_be_to_fe( void dce110_link_encoder_connect_dig_be_to_fe(
struct link_encoder *enc, struct link_encoder *enc,
enum engine_id engine, enum engine_id engine,
......
...@@ -361,7 +361,7 @@ static void program_grph_pixel_format( ...@@ -361,7 +361,7 @@ static void program_grph_pixel_format(
enum surface_pixel_format format) enum surface_pixel_format format)
{ {
uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */ uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
uint32_t grph_depth, grph_format; uint32_t grph_depth = 0, grph_format = 0;
uint32_t sign = 0, floating = 0; uint32_t sign = 0, floating = 0;
if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 || if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
...@@ -685,9 +685,6 @@ void dce_mem_input_construct( ...@@ -685,9 +685,6 @@ void dce_mem_input_construct(
dce_mi->regs = regs; dce_mi->regs = regs;
dce_mi->shifts = mi_shift; dce_mi->shifts = mi_shift;
dce_mi->masks = mi_mask; dce_mi->masks = mi_mask;
dce_mi->base.mpcc_id = 0xf;
dce_mi->base.opp_id = 0xf;
} }
void dce112_mem_input_construct( void dce112_mem_input_construct(
......
...@@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool) ...@@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL; *pool = NULL;
} }
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state) enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
{ {
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
......
...@@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool( ...@@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool(
uint8_t num_virtual_links, uint8_t num_virtual_links,
struct dc *dc); struct dc *dc);
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state); enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps);
enum dc_status dce100_add_stream_to_ctx( enum dc_status dce100_add_stream_to_ctx(
struct dc *dc, struct dc *dc,
......
...@@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor, ...@@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor,
compressor->base.lpt_channels_num = 0; compressor->base.lpt_channels_num = 0;
compressor->base.attached_inst = 0; compressor->base.attached_inst = 0;
compressor->base.is_enabled = false; compressor->base.is_enabled = false;
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
compressor->base.funcs = &dce110_compressor_funcs; compressor->base.funcs = &dce110_compressor_funcs;
#endif #endif
......
...@@ -47,7 +47,7 @@ void dce110_set_displaymarks( ...@@ -47,7 +47,7 @@ void dce110_set_displaymarks(
void dce110_enable_stream(struct pipe_ctx *pipe_ctx); void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
void dce110_disable_stream(struct pipe_ctx *pipe_ctx); void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option);
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings); struct dc_link_settings *link_settings);
...@@ -68,5 +68,14 @@ void dce110_fill_display_configs( ...@@ -68,5 +68,14 @@ void dce110_fill_display_configs(
uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
void dp_receiver_power_ctrl(struct dc_link *link, bool on); void dp_receiver_power_ctrl(struct dc_link *link, bool on);
void hwss_edp_power_control(
struct link_encoder *enc,
bool power_up);
void hwss_edp_backlight_control(
struct dc_link *link,
bool enable);
#endif /* __DC_HWSS_DCE110_H__ */ #endif /* __DC_HWSS_DCE110_H__ */
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dce110/dce110_compressor.h" #include "dce110/dce110_compressor.h"
#endif #endif
...@@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth( ...@@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth(
static bool dce110_validate_surface_sets( static bool dce110_validate_surface_sets(
struct dc_state *context) struct dc_state *context)
{ {
int i; int i, j;
for (i = 0; i < context->stream_count; i++) { for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0) if (context->stream_status[i].plane_count == 0)
...@@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets( ...@@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets(
if (context->stream_status[i].plane_count > 2) if (context->stream_status[i].plane_count > 2)
return false; return false;
if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) && for (j = 0; j < context->stream_status[i].plane_count; j++) {
(context->stream_status[i].plane_states[i]->src_rect.width > 1920 || struct dc_plane_state *plane =
context->stream_status[i].plane_states[i]->src_rect.height > 1080)) context->stream_status[i].plane_states[j];
return false;
/* irrespective of plane format, stream should be RGB encoded */ /* underlay validation */
if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB) if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
return false;
if ((plane->src_rect.width > 1920 ||
plane->src_rect.height > 1080))
return false;
/* irrespective of plane format,
* stream should be RGB encoded
*/
if (context->streams[i]->timing.pixel_encoding
!= PIXEL_ENCODING_RGB)
return false;
}
}
} }
return true; return true;
...@@ -1266,7 +1279,7 @@ static bool construct( ...@@ -1266,7 +1279,7 @@ static bool construct(
} }
} }
#ifdef ENABLE_FBC #if defined(CONFIG_DRM_AMD_DC_FBC)
dc->fbc_compressor = dce110_compressor_create(ctx); dc->fbc_compressor = dce110_compressor_create(ctx);
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \ dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
dcn10_mem_input.o dcn10_mpc.o \ dcn10_hubp.o dcn10_mpc.o \
dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o
AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "reg_helper.h" #include "reg_helper.h"
#include "dcn10_dpp.h" #include "dcn10_dpp.h"
#include "dcn10_dpp_cm_helper.h" #include "dcn10_cm_common.h"
#define REG(reg) reg #define REG(reg) reg
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
* *
*/ */
#ifndef __DAL_DPP_DCN10_CM_HELPER_H__ #ifndef __DAL_DCN10_CM_COMMON_H__
#define __DAL_DPP_DCN10_CM_HELPER_H__ #define __DAL_DCN10_CM_COMMON_H__
#define TF_HELPER_REG_FIELD_LIST(type) \ #define TF_HELPER_REG_FIELD_LIST(type) \
type exp_region0_lut_offset; \ type exp_region0_lut_offset; \
......
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
#ifndef __DAL_DPP_DCN10_H__ #ifndef __DAL_DPP_DCN10_H__
#define __DAL_DPP_DCN10_H__ #define __DAL_DPP_DCN10_H__
#include "transform.h" #include "dpp.h"
#define TO_DCN10_DPP(transform)\ #define TO_DCN10_DPP(dpp)\
container_of(transform, struct dcn10_dpp, base) container_of(dpp, struct dcn10_dpp, base)
/* TODO: Use correct number of taps. Using polaris values for now */ /* TODO: Use correct number of taps. Using polaris values for now */
#define LB_TOTAL_NUMBER_OF_ENTRIES 5124 #define LB_TOTAL_NUMBER_OF_ENTRIES 5124
...@@ -112,7 +112,9 @@ ...@@ -112,7 +112,9 @@
SRI(CM_DGAM_CONTROL, CM, id), \ SRI(CM_DGAM_CONTROL, CM, id), \
SRI(FORMAT_CONTROL, CNVC_CFG, id), \ SRI(FORMAT_CONTROL, CNVC_CFG, id), \
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id) SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
SRI(CURSOR0_COLOR1, CNVC_CUR, id)
...@@ -162,7 +164,8 @@ ...@@ -162,7 +164,8 @@
SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \ SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \ SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \ SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
SRI(CURSOR_CONTROL, CURSOR, id) SRI(CURSOR_CONTROL, CURSOR, id), \
SRI(CM_CMOUT_CONTROL, CM, id)
#define TF_REG_LIST_SH_MASK_DCN(mask_sh)\ #define TF_REG_LIST_SH_MASK_DCN(mask_sh)\
...@@ -302,7 +305,9 @@ ...@@ -302,7 +305,9 @@
TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \ TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh) TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\ #define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
TF_REG_LIST_SH_MASK_DCN(mask_sh),\ TF_REG_LIST_SH_MASK_DCN(mask_sh),\
...@@ -397,6 +402,7 @@ ...@@ -397,6 +402,7 @@
TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \ TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \
TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \ TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \ TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \
TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
...@@ -545,6 +551,7 @@ ...@@ -545,6 +551,7 @@
type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \ type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \
type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \ type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type CM_RGAM_LUT_MODE; \ type CM_RGAM_LUT_MODE; \
type CM_CMOUT_ROUND_TRUNC_MODE; \
type OBUF_BYPASS; \ type OBUF_BYPASS; \
type OBUF_H_2X_UPSCALE_EN; \ type OBUF_H_2X_UPSCALE_EN; \
type CM_BLNDGAM_LUT_MODE; \ type CM_BLNDGAM_LUT_MODE; \
...@@ -989,7 +996,9 @@ ...@@ -989,7 +996,9 @@
type CUR0_EXPANSION_MODE; \ type CUR0_EXPANSION_MODE; \
type CUR0_ENABLE; \ type CUR0_ENABLE; \
type CM_BYPASS; \ type CM_BYPASS; \
type FORMAT_CONTROL__ALPHA_EN type FORMAT_CONTROL__ALPHA_EN; \
type CUR0_COLOR0; \
type CUR0_COLOR1
...@@ -1075,6 +1084,7 @@ struct dcn_dpp_registers { ...@@ -1075,6 +1084,7 @@ struct dcn_dpp_registers {
uint32_t CM_RGAM_RAMA_REGION_0_1; uint32_t CM_RGAM_RAMA_REGION_0_1;
uint32_t CM_RGAM_RAMA_REGION_32_33; uint32_t CM_RGAM_RAMA_REGION_32_33;
uint32_t CM_RGAM_CONTROL; uint32_t CM_RGAM_CONTROL;
uint32_t CM_CMOUT_CONTROL;
uint32_t OBUF_CONTROL; uint32_t OBUF_CONTROL;
uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK; uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
uint32_t CM_BLNDGAM_CONTROL; uint32_t CM_BLNDGAM_CONTROL;
...@@ -1237,10 +1247,12 @@ struct dcn_dpp_registers { ...@@ -1237,10 +1247,12 @@ struct dcn_dpp_registers {
uint32_t CNVC_SURFACE_PIXEL_FORMAT; uint32_t CNVC_SURFACE_PIXEL_FORMAT;
uint32_t CURSOR_CONTROL; uint32_t CURSOR_CONTROL;
uint32_t CURSOR0_CONTROL; uint32_t CURSOR0_CONTROL;
uint32_t CURSOR0_COLOR0;
uint32_t CURSOR0_COLOR1;
}; };
struct dcn10_dpp { struct dcn10_dpp {
struct transform base; struct dpp base;
const struct dcn_dpp_registers *tf_regs; const struct dcn_dpp_registers *tf_regs;
const struct dcn_dpp_shift *tf_shift; const struct dcn_dpp_shift *tf_shift;
...@@ -1256,107 +1268,116 @@ struct dcn10_dpp { ...@@ -1256,107 +1268,116 @@ struct dcn10_dpp {
bool is_write_to_ram_a_safe; bool is_write_to_ram_a_safe;
}; };
enum dcn10_input_csc_select { enum dcn10_input_csc_select {
INPUT_CSC_SELECT_BYPASS = 0, INPUT_CSC_SELECT_BYPASS = 0,
INPUT_CSC_SELECT_ICSC, INPUT_CSC_SELECT_ICSC,
INPUT_CSC_SELECT_COMA INPUT_CSC_SELECT_COMA
}; };
void ippn10_degamma_ram_select( bool dpp1_dscl_is_lb_conf_valid(
struct transform *xfm_base, int ceil_vratio,
int num_partitions,
int vtaps);
void dpp1_dscl_calc_lb_num_partitions(
const struct scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
int *num_part_c);
void dpp1_degamma_ram_select(
struct dpp *dpp_base,
bool use_ram_a); bool use_ram_a);
void ippn10_program_degamma_luta_settings( void dpp1_program_degamma_luta_settings(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_params *params); const struct pwl_params *params);
void ippn10_program_degamma_lutb_settings( void dpp1_program_degamma_lutb_settings(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_params *params); const struct pwl_params *params);
void ippn10_program_degamma_lut( void dpp1_program_degamma_lut(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_result_data *rgb, const struct pwl_result_data *rgb,
uint32_t num, uint32_t num,
bool is_ram_a); bool is_ram_a);
void ippn10_power_on_degamma_lut( void dpp1_power_on_degamma_lut(
struct transform *xfm_base, struct dpp *dpp_base,
bool power_on); bool power_on);
void ippn10_program_input_csc( void dpp1_program_input_csc(
struct transform *xfm_base, struct dpp *dpp_base,
enum dc_color_space color_space, enum dc_color_space color_space,
enum dcn10_input_csc_select select); enum dcn10_input_csc_select select);
void ippn10_program_input_lut( void dpp1_program_input_lut(
struct transform *xfm_base, struct dpp *dpp_base,
const struct dc_gamma *gamma); const struct dc_gamma *gamma);
void ippn10_full_bypass(struct transform *xfm_base); void dpp1_full_bypass(struct dpp *dpp_base);
void ippn10_set_degamma( void dpp1_set_degamma(
struct transform *xfm_base, struct dpp *dpp_base,
enum ipp_degamma_mode mode); enum ipp_degamma_mode mode);
void ippn10_set_degamma_pwl(struct transform *xfm_base, void dpp1_set_degamma_pwl(struct dpp *dpp_base,
const struct pwl_params *params); const struct pwl_params *params);
bool dpp_get_optimal_number_of_taps( bool dpp_get_optimal_number_of_taps(
struct transform *xfm, struct dpp *dpp,
struct scaler_data *scl_data, struct scaler_data *scl_data,
const struct scaling_taps *in_taps); const struct scaling_taps *in_taps);
void dpp_reset(struct transform *xfm_base); void dpp_reset(struct dpp *dpp_base);
void dcn10_dpp_cm_program_regamma_lut( void dpp1_cm_program_regamma_lut(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_result_data *rgb, const struct pwl_result_data *rgb,
uint32_t num); uint32_t num);
void dcn10_dpp_cm_power_on_regamma_lut( void dpp1_cm_power_on_regamma_lut(
struct transform *xfm_base, struct dpp *dpp_base,
bool power_on); bool power_on);
void dcn10_dpp_cm_configure_regamma_lut( void dpp1_cm_configure_regamma_lut(
struct transform *xfm_base, struct dpp *dpp_base,
bool is_ram_a); bool is_ram_a);
/*program re gamma RAM A*/ /*program re gamma RAM A*/
void dcn10_dpp_cm_program_regamma_luta_settings( void dpp1_cm_program_regamma_luta_settings(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_params *params); const struct pwl_params *params);
/*program re gamma RAM B*/ /*program re gamma RAM B*/
void dcn10_dpp_cm_program_regamma_lutb_settings( void dpp1_cm_program_regamma_lutb_settings(
struct transform *xfm_base, struct dpp *dpp_base,
const struct pwl_params *params); const struct pwl_params *params);
void dcn10_dpp_cm_set_output_csc_adjustment( void dpp1_cm_set_output_csc_adjustment(
struct transform *xfm_base, struct dpp *dpp_base,
const struct out_csc_color_matrix *tbl_entry); const struct out_csc_color_matrix *tbl_entry);
void dcn10_dpp_cm_set_output_csc_default( void dpp1_cm_set_output_csc_default(
struct transform *xfm_base, struct dpp *dpp_base,
const struct default_adjustment *default_adjust); const struct default_adjustment *default_adjust);
void dcn10_dpp_cm_set_gamut_remap( void dpp1_cm_set_gamut_remap(
struct transform *xfm, struct dpp *dpp,
const struct xfm_grph_csc_adjustment *adjust); const struct dpp_grph_csc_adjustment *adjust);
void dcn10_dpp_dscl_set_scaler_manual_scale( void dpp1_dscl_set_scaler_manual_scale(
struct transform *xfm_base, struct dpp *dpp_base,
const struct scaler_data *scl_data); const struct scaler_data *scl_data);
void ippn10_cnv_setup ( void dpp1_cnv_setup (
struct transform *xfm_base, struct dpp *dpp_base,
enum surface_pixel_format input_format, enum surface_pixel_format input_format,
enum expansion_mode mode); enum expansion_mode mode);
void ippn10_full_bypass(struct transform *xfm_base); void dpp1_full_bypass(struct dpp *dpp_base);
void dcn10_dpp_construct(struct dcn10_dpp *xfm110, void dpp1_construct(struct dcn10_dpp *dpp1,
struct dc_context *ctx, struct dc_context *ctx,
uint32_t inst, uint32_t inst,
const struct dcn_dpp_registers *tf_regs, const struct dcn_dpp_registers *tf_regs,
......
...@@ -37,188 +37,6 @@ ...@@ -37,188 +37,6 @@
#define CTX \ #define CTX \
ippn10->base.ctx ippn10->base.ctx
static bool ippn10_cursor_program_control(
struct dcn10_ipp *ippn10,
bool pixel_data_invert,
enum dc_cursor_color_format color_format)
{
if (REG(CURSOR_SETTINS))
REG_SET_2(CURSOR_SETTINS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
else
REG_SET_2(CURSOR_SETTINGS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
REG_UPDATE_2(CURSOR0_CONTROL,
CUR0_MODE, color_format,
CUR0_EXPANSION_MODE, 0);
if (color_format == CURSOR_MODE_MONO) {
/* todo: clarify what to program these to */
REG_UPDATE(CURSOR0_COLOR0,
CUR0_COLOR0, 0x00000000);
REG_UPDATE(CURSOR0_COLOR1,
CUR0_COLOR1, 0xFFFFFFFF);
}
/* TODO: Fixed vs float */
REG_UPDATE_3(FORMAT_CONTROL,
CNVC_BYPASS, 0,
ALPHA_EN, 1,
FORMAT_EXPANSION_MODE, 0);
return true;
}
enum cursor_pitch {
CURSOR_PITCH_64_PIXELS = 0,
CURSOR_PITCH_128_PIXELS,
CURSOR_PITCH_256_PIXELS
};
enum cursor_lines_per_chunk {
CURSOR_LINE_PER_CHUNK_2 = 1,
CURSOR_LINE_PER_CHUNK_4,
CURSOR_LINE_PER_CHUNK_8,
CURSOR_LINE_PER_CHUNK_16
};
static enum cursor_pitch ippn10_get_cursor_pitch(
unsigned int pitch)
{
enum cursor_pitch hw_pitch;
switch (pitch) {
case 64:
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
case 128:
hw_pitch = CURSOR_PITCH_128_PIXELS;
break;
case 256:
hw_pitch = CURSOR_PITCH_256_PIXELS;
break;
default:
DC_ERR("Invalid cursor pitch of %d. "
"Only 64/128/256 is supported on DCN.\n", pitch);
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
}
return hw_pitch;
}
static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
unsigned int cur_width,
enum dc_cursor_color_format format)
{
enum cursor_lines_per_chunk line_per_chunk;
if (format == CURSOR_MODE_MONO)
/* impl B. expansion in CUR Buffer reader */
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 32)
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 64)
line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
else if (cur_width <= 128)
line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
else
line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
return line_per_chunk;
}
static void ippn10_cursor_set_attributes(
struct input_pixel_processor *ipp,
const struct dc_cursor_attributes *attr)
{
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
attr->width, attr->color_format);
ippn10->curs_attr = *attr;
REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
REG_UPDATE(CURSOR_SURFACE_ADDRESS,
CURSOR_SURFACE_ADDRESS, attr->address.low_part);
REG_UPDATE_2(CURSOR_SIZE,
CURSOR_WIDTH, attr->width,
CURSOR_HEIGHT, attr->height);
REG_UPDATE_3(CURSOR_CONTROL,
CURSOR_MODE, attr->color_format,
CURSOR_PITCH, hw_pitch,
CURSOR_LINES_PER_CHUNK, lpc);
ippn10_cursor_program_control(ippn10,
attr->attribute_flags.bits.INVERT_PIXEL_DATA,
attr->color_format);
}
static void ippn10_cursor_set_position(
struct input_pixel_processor *ipp,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param)
{
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
uint32_t cur_en = pos->enable ? 1 : 0;
uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
/*
* Guard aganst cursor_set_position() from being called with invalid
* attributes
*
* TODO: Look at combining cursor_set_position() and
* cursor_set_attributes() into cursor_update()
*/
if (ippn10->curs_attr.address.quad_part == 0)
return;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
ASSERT(param->h_scale_ratio.value);
if (param->h_scale_ratio.value)
dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
dal_fixed31_32_from_int(dst_x_offset),
param->h_scale_ratio));
if (src_x_offset >= (int)param->viewport_width)
cur_en = 0; /* not visible beyond right edge*/
if (src_x_offset + (int)ippn10->curs_attr.width < 0)
cur_en = 0; /* not visible beyond left edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
REG_UPDATE(CURSOR_CONTROL,
CURSOR_ENABLE, cur_en);
REG_UPDATE(CURSOR0_CONTROL,
CUR0_ENABLE, cur_en);
REG_SET_2(CURSOR_POSITION, 0,
CURSOR_X_POSITION, pos->x,
CURSOR_Y_POSITION, pos->y);
REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, pos->x_hotspot,
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
REG_SET(CURSOR_DST_OFFSET, 0,
CURSOR_DST_X_OFFSET, dst_x_offset);
/* TODO Handle surface pixel formats other than 4:4:4 */
}
/*****************************************/ /*****************************************/
/* Constructor, Destructor */ /* Constructor, Destructor */
/*****************************************/ /*****************************************/
...@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp) ...@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
} }
static const struct ipp_funcs dcn10_ipp_funcs = { static const struct ipp_funcs dcn10_ipp_funcs = {
.ipp_cursor_set_attributes = ippn10_cursor_set_attributes,
.ipp_cursor_set_position = ippn10_cursor_set_position,
.ipp_set_degamma = NULL,
.ipp_program_input_lut = NULL,
.ipp_full_bypass = NULL,
.ipp_setup = NULL,
.ipp_program_degamma_pwl = NULL,
.ipp_destroy = dcn10_ipp_destroy .ipp_destroy = dcn10_ipp_destroy
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment