summaryrefslogtreecommitdiff
path: root/drivers/staging/msm/mddihosti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/msm/mddihosti.c')
-rw-r--r--drivers/staging/msm/mddihosti.c2239
1 files changed, 0 insertions, 2239 deletions
diff --git a/drivers/staging/msm/mddihosti.c b/drivers/staging/msm/mddihosti.c
deleted file mode 100644
index f9d6e91e8d5d..000000000000
--- a/drivers/staging/msm/mddihosti.c
+++ /dev/null
@@ -1,2239 +0,0 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-
-#include "msm_fb_panel.h"
-#include "mddihost.h"
-#include "mddihosti.h"
-
-#define FEATURE_MDDI_UNDERRUN_RECOVERY
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
-static void mddi_read_rev_packet(byte *data_ptr);
-#endif
-
-struct timer_list mddi_host_timer;
-
-#define MDDI_DEFAULT_TIMER_LENGTH 5000 /* 5 seconds */
-uint32 mddi_rtd_frequency = 60000; /* send RTD every 60 seconds */
-uint32 mddi_client_status_frequency = 60000; /* get status pkt every 60 secs */
-
-boolean mddi_vsync_detect_enabled = FALSE;
-mddi_gpio_info_type mddi_gpio;
-
-uint32 mddi_host_core_version;
-boolean mddi_debug_log_statistics = FALSE;
-/* #define FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION */
-/* default to TRUE in case MDP does not vote */
-static boolean mddi_host_mdp_active_flag = TRUE;
-static uint32 mddi_log_stats_counter;
-uint32 mddi_log_stats_frequency = 4000;
-
-#define MDDI_DEFAULT_REV_PKT_SIZE 0x20
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
-static boolean mddi_rev_ptr_workaround = TRUE;
-static uint32 mddi_reg_read_retry;
-static uint32 mddi_reg_read_retry_max = 20;
-static boolean mddi_enable_reg_read_retry = TRUE;
-static boolean mddi_enable_reg_read_retry_once = FALSE;
-
-#define MDDI_MAX_REV_PKT_SIZE 0x60
-
-#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60
-
-#define MDDI_VIDEO_REV_PKT_SIZE 0x40
-#define MDDI_REV_BUFFER_SIZE MDDI_MAX_REV_PKT_SIZE
-static byte rev_packet_data[MDDI_MAX_REV_PKT_SIZE];
-#endif /* FEATURE_MDDI_DISABLE_REVERSE */
-/* leave these variables so graphics will compile */
-
-#define MDDI_MAX_REV_DATA_SIZE 128
-/*lint -d__align(x) */
-boolean mddi_debug_clear_rev_data = TRUE;
-
-uint32 *mddi_reg_read_value_ptr;
-
-mddi_client_capability_type mddi_client_capability_pkt;
-static boolean mddi_client_capability_request = FALSE;
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
-
-#define MAX_MDDI_REV_HANDLERS 2
-#define INVALID_PKT_TYPE 0xFFFF
-
-typedef struct {
- mddi_rev_handler_type handler; /* ISR to be executed */
- uint16 pkt_type;
-} mddi_rev_pkt_handler_type;
-static mddi_rev_pkt_handler_type mddi_rev_pkt_handler[MAX_MDDI_REV_HANDLERS] =
- { {NULL, INVALID_PKT_TYPE}, {NULL, INVALID_PKT_TYPE} };
-
-static boolean mddi_rev_encap_user_request = FALSE;
-static mddi_linked_list_notify_type mddi_rev_user;
-
-spinlock_t mddi_host_spin_lock;
-extern uint32 mdp_in_processing;
-#endif
-
-typedef enum {
- MDDI_REV_IDLE
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- , MDDI_REV_REG_READ_ISSUED,
- MDDI_REV_REG_READ_SENT,
- MDDI_REV_ENCAP_ISSUED,
- MDDI_REV_STATUS_REQ_ISSUED,
- MDDI_REV_CLIENT_CAP_ISSUED
-#endif
-} mddi_rev_link_state_type;
-
-typedef enum {
- MDDI_LINK_DISABLED,
- MDDI_LINK_HIBERNATING,
- MDDI_LINK_ACTIVATING,
- MDDI_LINK_ACTIVE
-} mddi_host_link_state_type;
-
-typedef struct {
- uint32 count;
- uint32 in_count;
- uint32 disp_req_count;
- uint32 state_change_count;
- uint32 ll_done_count;
- uint32 rev_avail_count;
- uint32 error_count;
- uint32 rev_encap_count;
- uint32 llist_ptr_write_1;
- uint32 llist_ptr_write_2;
-} mddi_host_int_type;
-
-typedef struct {
- uint32 fwd_crc_count;
- uint32 rev_crc_count;
- uint32 pri_underflow;
- uint32 sec_underflow;
- uint32 rev_overflow;
- uint32 pri_overwrite;
- uint32 sec_overwrite;
- uint32 rev_overwrite;
- uint32 dma_failure;
- uint32 rtd_failure;
- uint32 reg_read_failure;
-#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
- uint32 pri_underrun_detected;
-#endif
-} mddi_host_stat_type;
-
-typedef struct {
- uint32 rtd_cnt;
- uint32 rev_enc_cnt;
- uint32 vid_cnt;
- uint32 reg_acc_cnt;
- uint32 cli_stat_cnt;
- uint32 cli_cap_cnt;
- uint32 reg_read_cnt;
- uint32 link_active_cnt;
- uint32 link_hibernate_cnt;
- uint32 vsync_response_cnt;
- uint32 fwd_crc_cnt;
- uint32 rev_crc_cnt;
-} mddi_log_params_struct_type;
-
-typedef struct {
- uint32 rtd_value;
- uint32 rtd_counter;
- uint32 client_status_cnt;
- boolean rev_ptr_written;
- uint8 *rev_ptr_start;
- uint8 *rev_ptr_curr;
- uint32 mddi_rev_ptr_write_val;
- dma_addr_t rev_data_dma_addr;
- uint16 rev_pkt_size;
- mddi_rev_link_state_type rev_state;
- mddi_host_link_state_type link_state;
- mddi_host_driver_state_type driver_state;
- boolean disable_hibernation;
- uint32 saved_int_reg;
- uint32 saved_int_en;
- mddi_linked_list_type *llist_ptr;
- dma_addr_t llist_dma_addr;
- mddi_linked_list_type *llist_dma_ptr;
- uint32 *rev_data_buf;
- struct completion mddi_llist_avail_comp;
- boolean mddi_waiting_for_llist_avail;
- mddi_host_int_type int_type;
- mddi_host_stat_type stats;
- mddi_log_params_struct_type log_parms;
- mddi_llist_info_type llist_info;
- mddi_linked_list_notify_type llist_notify[MDDI_MAX_NUM_LLIST_ITEMS];
-} mddi_host_cntl_type;
-
-static mddi_host_type mddi_curr_host = MDDI_HOST_PRIM;
-static mddi_host_cntl_type mhctl[MDDI_NUM_HOST_CORES];
-mddi_linked_list_type *llist_extern[MDDI_NUM_HOST_CORES];
-mddi_linked_list_type *llist_dma_extern[MDDI_NUM_HOST_CORES];
-mddi_linked_list_notify_type *llist_extern_notify[MDDI_NUM_HOST_CORES];
-static mddi_log_params_struct_type prev_parms[MDDI_NUM_HOST_CORES];
-
-extern uint32 mdp_total_vdopkts;
-
-static boolean mddi_host_io_clock_on = FALSE;
-static boolean mddi_host_hclk_on = FALSE;
-
-int int_mddi_pri_flag = FALSE;
-int int_mddi_ext_flag = FALSE;
-
-static void mddi_report_errors(uint32 int_reg)
-{
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if (int_reg & MDDI_INT_PRI_UNDERFLOW) {
- pmhctl->stats.pri_underflow++;
- MDDI_MSG_ERR("!!! MDDI Primary Underflow !!!\n");
- }
- if (int_reg & MDDI_INT_SEC_UNDERFLOW) {
- pmhctl->stats.sec_underflow++;
- MDDI_MSG_ERR("!!! MDDI Secondary Underflow !!!\n");
- }
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (int_reg & MDDI_INT_REV_OVERFLOW) {
- pmhctl->stats.rev_overflow++;
- MDDI_MSG_ERR("!!! MDDI Reverse Overflow !!!\n");
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
-
- }
- if (int_reg & MDDI_INT_CRC_ERROR)
- MDDI_MSG_ERR("!!! MDDI Reverse CRC Error !!!\n");
-#endif
- if (int_reg & MDDI_INT_PRI_OVERWRITE) {
- pmhctl->stats.pri_overwrite++;
- MDDI_MSG_ERR("!!! MDDI Primary Overwrite !!!\n");
- }
- if (int_reg & MDDI_INT_SEC_OVERWRITE) {
- pmhctl->stats.sec_overwrite++;
- MDDI_MSG_ERR("!!! MDDI Secondary Overwrite !!!\n");
- }
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (int_reg & MDDI_INT_REV_OVERWRITE) {
- pmhctl->stats.rev_overwrite++;
- /* This will show up normally and is not a problem */
- MDDI_MSG_DEBUG("MDDI Reverse Overwrite!\n");
- }
- if (int_reg & MDDI_INT_RTD_FAILURE) {
- mddi_host_reg_outm(INTEN, MDDI_INT_RTD_FAILURE, 0);
- pmhctl->stats.rtd_failure++;
- MDDI_MSG_ERR("!!! MDDI RTD Failure !!!\n");
- }
-#endif
- if (int_reg & MDDI_INT_DMA_FAILURE) {
- pmhctl->stats.dma_failure++;
- MDDI_MSG_ERR("!!! MDDI DMA Abort !!!\n");
- }
-}
-
-static void mddi_host_enable_io_clock(void)
-{
- if (!MDDI_HOST_IS_IO_CLOCK_ON)
- MDDI_HOST_ENABLE_IO_CLOCK;
-}
-
-static void mddi_host_enable_hclk(void)
-{
-
- if (!MDDI_HOST_IS_HCLK_ON)
- MDDI_HOST_ENABLE_HCLK;
-}
-
-static void mddi_host_disable_io_clock(void)
-{
-#ifndef FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
- if (MDDI_HOST_IS_IO_CLOCK_ON)
- MDDI_HOST_DISABLE_IO_CLOCK;
-#endif
-}
-
-static void mddi_host_disable_hclk(void)
-{
-#ifndef FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
- if (MDDI_HOST_IS_HCLK_ON)
- MDDI_HOST_DISABLE_HCLK;
-#endif
-}
-
-static void mddi_vote_to_sleep(mddi_host_type host_idx, boolean sleep)
-{
- uint16 vote_mask;
-
- if (host_idx == MDDI_HOST_PRIM)
- vote_mask = 0x01;
- else
- vote_mask = 0x02;
-}
-
-static void mddi_report_state_change(uint32 int_reg)
-{
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if ((pmhctl->saved_int_reg & MDDI_INT_IN_HIBERNATION) &&
- (pmhctl->saved_int_reg & MDDI_INT_LINK_ACTIVE)) {
- /* recover from condition where the io_clock was turned off by the
- clock driver during a transition to hibernation. The io_clock
- disable is to prevent MDP/MDDI underruns when changing ARM
- clock speeds. In the process of halting the ARM, the hclk
- divider needs to be set to 1. When it is set to 1, there is
- a small time (usecs) when hclk is off or slow, and this can
- cause an underrun. To prevent the underrun, clock driver turns
- off the MDDI io_clock before making the change. */
- mddi_host_reg_out(CMD, MDDI_CMD_POWERUP);
- }
-
- if (int_reg & MDDI_INT_LINK_ACTIVE) {
- pmhctl->link_state = MDDI_LINK_ACTIVE;
- pmhctl->log_parms.link_active_cnt++;
- pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
- MDDI_MSG_DEBUG("!!! MDDI Active RTD:0x%x!!!\n",
- pmhctl->rtd_value);
- /* now interrupt on hibernation */
- mddi_host_reg_outm(INTEN,
- (MDDI_INT_IN_HIBERNATION |
- MDDI_INT_LINK_ACTIVE),
- MDDI_INT_IN_HIBERNATION);
-
-#ifdef DEBUG_MDDIHOSTI
- /* if gpio interrupt is enabled, start polling at fastest
- * registered rate
- */
- if (mddi_gpio.polling_enabled) {
- timer_reg(&mddi_gpio_poll_timer,
- mddi_gpio_poll_timer_cb, 0, mddi_gpio.polling_interval, 0);
- }
-#endif
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (mddi_rev_ptr_workaround) {
- /* HW CR: need to reset reverse register stuff */
- pmhctl->rev_ptr_written = FALSE;
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- }
-#endif
- /* vote on sleep */
- mddi_vote_to_sleep(host_idx, FALSE);
-
- if (host_idx == MDDI_HOST_PRIM) {
- if (mddi_vsync_detect_enabled) {
- /*
- * Indicate to client specific code that vsync
- * was enabled, but we did not detect a client
- * intiated wakeup. The client specific
- * handler can either reassert vsync detection,
- * or treat this as a valid vsync.
- */
- mddi_client_lcd_vsync_detected(FALSE);
- pmhctl->log_parms.vsync_response_cnt++;
- }
- }
- }
- if (int_reg & MDDI_INT_IN_HIBERNATION) {
- pmhctl->link_state = MDDI_LINK_HIBERNATING;
- pmhctl->log_parms.link_hibernate_cnt++;
- MDDI_MSG_DEBUG("!!! MDDI Hibernating !!!\n");
- /* now interrupt on link_active */
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- mddi_host_reg_outm(INTEN,
- (MDDI_INT_MDDI_IN |
- MDDI_INT_IN_HIBERNATION |
- MDDI_INT_LINK_ACTIVE),
- MDDI_INT_LINK_ACTIVE);
-#else
- mddi_host_reg_outm(INTEN,
- (MDDI_INT_MDDI_IN |
- MDDI_INT_IN_HIBERNATION |
- MDDI_INT_LINK_ACTIVE),
- (MDDI_INT_MDDI_IN | MDDI_INT_LINK_ACTIVE));
-
- pmhctl->rtd_counter = mddi_rtd_frequency;
-
- if (pmhctl->rev_state != MDDI_REV_IDLE) {
- /* a rev_encap will not wake up the link, so we do that here */
- pmhctl->link_state = MDDI_LINK_ACTIVATING;
- mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
- }
-#endif
-
- if (pmhctl->disable_hibernation) {
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
- mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
- pmhctl->link_state = MDDI_LINK_ACTIVATING;
- }
-#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
- if ((pmhctl->llist_info.transmitting_start_idx !=
- UNASSIGNED_INDEX)
- &&
- ((pmhctl->
- saved_int_reg & (MDDI_INT_PRI_LINK_LIST_DONE |
- MDDI_INT_PRI_PTR_READ)) ==
- MDDI_INT_PRI_PTR_READ)) {
- mddi_linked_list_type *llist_dma;
- llist_dma = pmhctl->llist_dma_ptr;
- /*
- * All indications are that we have not received a
- * linked list done interrupt, due to an underrun
- * condition. Recovery attempt is to send again.
- */
- dma_coherent_pre_ops();
- /* Write to primary pointer register again */
- mddi_host_reg_out(PRI_PTR,
- &llist_dma[pmhctl->llist_info.
- transmitting_start_idx]);
- pmhctl->stats.pri_underrun_detected++;
- }
-#endif
-
- /* vote on sleep */
- if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
- mddi_vote_to_sleep(host_idx, TRUE);
- }
-
-#ifdef DEBUG_MDDIHOSTI
- /* need to stop polling timer */
- if (mddi_gpio.polling_enabled) {
- (void) timer_clr(&mddi_gpio_poll_timer, T_NONE);
- }
-#endif
- }
-}
-
-void mddi_host_timer_service(unsigned long data)
-{
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- unsigned long flags;
-#endif
- mddi_host_type host_idx;
- mddi_host_cntl_type *pmhctl;
-
- unsigned long time_ms = MDDI_DEFAULT_TIMER_LENGTH;
- init_timer(&mddi_host_timer);
- mddi_host_timer.function = mddi_host_timer_service;
- mddi_host_timer.data = 0;
-
- mddi_host_timer.expires = jiffies + ((time_ms * HZ) / 1000);
- add_timer(&mddi_host_timer);
-
- for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
- host_idx++) {
- pmhctl = &(mhctl[host_idx]);
- mddi_log_stats_counter += (uint32) time_ms;
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- pmhctl->rtd_counter += (uint32) time_ms;
- pmhctl->client_status_cnt += (uint32) time_ms;
-
- if (host_idx == MDDI_HOST_PRIM) {
- if (pmhctl->client_status_cnt >=
- mddi_client_status_frequency) {
- if ((pmhctl->link_state ==
- MDDI_LINK_HIBERNATING)
- && (pmhctl->client_status_cnt >
- mddi_client_status_frequency)) {
- /*
- * special case where we are hibernating
- * and mddi_host_isr is not firing, so
- * kick the link so that the status can
- * be retrieved
- */
-
- /* need to wake up link before issuing
- * rev encap command
- */
- MDDI_MSG_INFO("wake up link!\n");
- spin_lock_irqsave(&mddi_host_spin_lock,
- flags);
- mddi_host_enable_hclk();
- mddi_host_enable_io_clock();
- pmhctl->link_state =
- MDDI_LINK_ACTIVATING;
- mddi_host_reg_out(CMD,
- MDDI_CMD_LINK_ACTIVE);
- spin_unlock_irqrestore
- (&mddi_host_spin_lock, flags);
- } else
- if ((pmhctl->link_state == MDDI_LINK_ACTIVE)
- && pmhctl->disable_hibernation) {
- /*
- * special case where we have disabled
- * hibernation and mddi_host_isr
- * is not firing, so enable interrupt
- * for no pkts pending, which will
- * generate an interrupt
- */
- MDDI_MSG_INFO("kick isr!\n");
- spin_lock_irqsave(&mddi_host_spin_lock,
- flags);
- mddi_host_enable_hclk();
- mddi_host_reg_outm(INTEN,
- MDDI_INT_NO_CMD_PKTS_PEND,
- MDDI_INT_NO_CMD_PKTS_PEND);
- spin_unlock_irqrestore
- (&mddi_host_spin_lock, flags);
- }
- }
- }
-#endif /* #ifndef FEATURE_MDDI_DISABLE_REVERSE */
- }
-
- /* Check if logging is turned on */
- for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
- host_idx++) {
- mddi_log_params_struct_type *prev_ptr = &(prev_parms[host_idx]);
- pmhctl = &(mhctl[host_idx]);
-
- if (mddi_debug_log_statistics) {
-
- /* get video pkt count from MDP, since MDDI sw cannot know this */
- pmhctl->log_parms.vid_cnt = mdp_total_vdopkts;
-
- if (mddi_log_stats_counter >= mddi_log_stats_frequency) {
- /* mddi_log_stats_counter = 0; */
- if (mddi_debug_log_statistics) {
- MDDI_MSG_NOTICE
- ("MDDI Statistics since last report:\n");
- MDDI_MSG_NOTICE(" Packets sent:\n");
- MDDI_MSG_NOTICE
- (" %d RTD packet(s)\n",
- pmhctl->log_parms.rtd_cnt -
- prev_ptr->rtd_cnt);
- if (prev_ptr->rtd_cnt !=
- pmhctl->log_parms.rtd_cnt) {
- unsigned long flags;
- spin_lock_irqsave
- (&mddi_host_spin_lock,
- flags);
- mddi_host_enable_hclk();
- pmhctl->rtd_value =
- mddi_host_reg_in(RTD_VAL);
- spin_unlock_irqrestore
- (&mddi_host_spin_lock,
- flags);
- MDDI_MSG_NOTICE
- (" RTD value=%d\n",
- pmhctl->rtd_value);
- }
- MDDI_MSG_NOTICE
- (" %d VIDEO packets\n",
- pmhctl->log_parms.vid_cnt -
- prev_ptr->vid_cnt);
- MDDI_MSG_NOTICE
- (" %d Register Access packets\n",
- pmhctl->log_parms.reg_acc_cnt -
- prev_ptr->reg_acc_cnt);
- MDDI_MSG_NOTICE
- (" %d Reverse Encapsulation packet(s)\n",
- pmhctl->log_parms.rev_enc_cnt -
- prev_ptr->rev_enc_cnt);
- if (prev_ptr->rev_enc_cnt !=
- pmhctl->log_parms.rev_enc_cnt) {
- /* report # of reverse CRC errors */
- MDDI_MSG_NOTICE
- (" %d reverse CRC errors detected\n",
- pmhctl->log_parms.
- rev_crc_cnt -
- prev_ptr->rev_crc_cnt);
- }
- MDDI_MSG_NOTICE
- (" Packets received:\n");
- MDDI_MSG_NOTICE
- (" %d Client Status packets",
- pmhctl->log_parms.cli_stat_cnt -
- prev_ptr->cli_stat_cnt);
- if (prev_ptr->cli_stat_cnt !=
- pmhctl->log_parms.cli_stat_cnt) {
- MDDI_MSG_NOTICE
- (" %d forward CRC errors reported\n",
- pmhctl->log_parms.
- fwd_crc_cnt -
- prev_ptr->fwd_crc_cnt);
- }
- MDDI_MSG_NOTICE
- (" %d Register Access Read packets\n",
- pmhctl->log_parms.reg_read_cnt -
- prev_ptr->reg_read_cnt);
-
- if (pmhctl->link_state ==
- MDDI_LINK_ACTIVE) {
- MDDI_MSG_NOTICE
- (" Current Link Status: Active\n");
- } else
- if ((pmhctl->link_state ==
- MDDI_LINK_HIBERNATING)
- || (pmhctl->link_state ==
- MDDI_LINK_ACTIVATING)) {
- MDDI_MSG_NOTICE
- (" Current Link Status: Hibernation\n");
- } else {
- MDDI_MSG_NOTICE
- (" Current Link Status: Inactive\n");
- }
- MDDI_MSG_NOTICE
- (" Active state entered %d times\n",
- pmhctl->log_parms.link_active_cnt -
- prev_ptr->link_active_cnt);
- MDDI_MSG_NOTICE
- (" Hibernation state entered %d times\n",
- pmhctl->log_parms.
- link_hibernate_cnt -
- prev_ptr->link_hibernate_cnt);
- }
- }
- prev_parms[host_idx] = pmhctl->log_parms;
- }
- }
- if (mddi_log_stats_counter >= mddi_log_stats_frequency)
- mddi_log_stats_counter = 0;
-
- return;
-} /* mddi_host_timer_cb */
-
-static void mddi_process_link_list_done(void)
-{
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- /* normal forward linked list packet(s) were sent */
- if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
- MDDI_MSG_ERR("**** getting LL done, but no list ****\n");
- } else {
- uint16 idx;
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (pmhctl->rev_state == MDDI_REV_REG_READ_ISSUED) {
- /* special case where a register read packet was sent */
- pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
- if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
- MDDI_MSG_ERR
- ("**** getting LL done, but no list ****\n");
- }
- }
-#endif
- for (idx = pmhctl->llist_info.transmitting_start_idx;;) {
- uint16 next_idx = pmhctl->llist_notify[idx].next_idx;
- /* with reg read we don't release the waiting tcb until after
- * the reverse encapsulation has completed.
- */
- if (idx != pmhctl->llist_info.reg_read_idx) {
- /* notify task that may be waiting on this completion */
- if (pmhctl->llist_notify[idx].waiting) {
- complete(&
- (pmhctl->llist_notify[idx].
- done_comp));
- }
- if (pmhctl->llist_notify[idx].done_cb != NULL) {
- (*(pmhctl->llist_notify[idx].done_cb))
- ();
- }
-
- pmhctl->llist_notify[idx].in_use = FALSE;
- pmhctl->llist_notify[idx].waiting = FALSE;
- pmhctl->llist_notify[idx].done_cb = NULL;
- if (idx < MDDI_NUM_DYNAMIC_LLIST_ITEMS) {
- /* static LLIST items are configured only once */
- pmhctl->llist_notify[idx].next_idx =
- UNASSIGNED_INDEX;
- }
- /*
- * currently, all linked list packets are
- * register access, so we can increment the
- * counter for that packet type here.
- */
- pmhctl->log_parms.reg_acc_cnt++;
- }
- if (idx == pmhctl->llist_info.transmitting_end_idx)
- break;
- idx = next_idx;
- if (idx == UNASSIGNED_INDEX)
- MDDI_MSG_CRIT("MDDI linked list corruption!\n");
- }
-
- pmhctl->llist_info.transmitting_start_idx = UNASSIGNED_INDEX;
- pmhctl->llist_info.transmitting_end_idx = UNASSIGNED_INDEX;
-
- if (pmhctl->mddi_waiting_for_llist_avail) {
- if (!
- (pmhctl->
- llist_notify[pmhctl->llist_info.next_free_idx].
- in_use)) {
- pmhctl->mddi_waiting_for_llist_avail = FALSE;
- complete(&(pmhctl->mddi_llist_avail_comp));
- }
- }
- }
-
- /* Turn off MDDI_INT_PRI_LINK_LIST_DONE interrupt */
- mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, 0);
-
-}
-
-static void mddi_queue_forward_linked_list(void)
-{
- uint16 first_pkt_index;
- mddi_linked_list_type *llist_dma;
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
- llist_dma = pmhctl->llist_dma_ptr;
-
- first_pkt_index = UNASSIGNED_INDEX;
-
- if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (pmhctl->llist_info.reg_read_waiting) {
- if (pmhctl->rev_state == MDDI_REV_IDLE) {
- /*
- * we have a register read to send and
- * can send it now
- */
- pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
- mddi_reg_read_retry = 0;
- first_pkt_index =
- pmhctl->llist_info.waiting_start_idx;
- pmhctl->llist_info.reg_read_waiting = FALSE;
- }
- } else
-#endif
- {
- /*
- * not register read to worry about, go ahead and write
- * anything that may be on the waiting list.
- */
- first_pkt_index = pmhctl->llist_info.waiting_start_idx;
- }
- }
-
- if (first_pkt_index != UNASSIGNED_INDEX) {
- pmhctl->llist_info.transmitting_start_idx =
- pmhctl->llist_info.waiting_start_idx;
- pmhctl->llist_info.transmitting_end_idx =
- pmhctl->llist_info.waiting_end_idx;
- pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
- pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
-
- /* write to the primary pointer register */
- MDDI_MSG_DEBUG("MDDI writing primary ptr with idx=%d\n",
- first_pkt_index);
-
- pmhctl->int_type.llist_ptr_write_2++;
-
- dma_coherent_pre_ops();
- mddi_host_reg_out(PRI_PTR, &llist_dma[first_pkt_index]);
-
- /* enable interrupt when complete */
- mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
- MDDI_INT_PRI_LINK_LIST_DONE);
-
- }
-
-}
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
-static void mddi_read_rev_packet(byte *data_ptr)
-{
- uint16 i, length;
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- uint8 *rev_ptr_overflow =
- (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE);
-
- /* first determine the length and handle invalid lengths */
- length = *pmhctl->rev_ptr_curr++;
- if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- length |= ((*pmhctl->rev_ptr_curr++) << 8);
- if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- if (length > (pmhctl->rev_pkt_size - 2)) {
- MDDI_MSG_ERR("Invalid rev pkt length %d\n", length);
- /* rev_pkt_size should always be <= rev_ptr_size so limit to packet size */
- length = pmhctl->rev_pkt_size - 2;
- }
-
- /* If the data pointer is NULL, just increment the pmhctl->rev_ptr_curr.
- * Loop around if necessary. Don't bother reading the data.
- */
- if (data_ptr == NULL) {
- pmhctl->rev_ptr_curr += length;
- if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
- pmhctl->rev_ptr_curr -= MDDI_REV_BUFFER_SIZE;
- return;
- }
-
- data_ptr[0] = length & 0x0ff;
- data_ptr[1] = length >> 8;
- data_ptr += 2;
- /* copy the data to data_ptr byte-at-a-time */
- for (i = 0; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow);
- i++)
- *data_ptr++ = *pmhctl->rev_ptr_curr++;
- if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- for (; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); i++)
- *data_ptr++ = *pmhctl->rev_ptr_curr++;
-}
-
-static void mddi_process_rev_packets(void)
-{
- uint32 rev_packet_count;
- word i;
- uint32 crc_errors;
- boolean mddi_reg_read_successful = FALSE;
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- pmhctl->log_parms.rev_enc_cnt++;
- if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
- (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED) &&
- (pmhctl->rev_state != MDDI_REV_CLIENT_CAP_ISSUED)) {
- MDDI_MSG_ERR("Wrong state %d for reverse int\n",
- pmhctl->rev_state);
- }
- /* Turn off MDDI_INT_REV_AVAIL interrupt */
- mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, 0);
-
- /* Clear rev data avail int */
- mddi_host_reg_out(INT, MDDI_INT_REV_DATA_AVAIL);
-
- /* Get Number of packets */
- rev_packet_count = mddi_host_reg_in(REV_PKT_CNT);
-
-#ifndef T_MSM7500
- /* Clear out rev packet counter */
- mddi_host_reg_out(REV_PKT_CNT, 0x0000);
-#endif
-
-#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
- if ((pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) &&
- (rev_packet_count > 0) &&
- (mddi_host_core_version == 0x28 ||
- mddi_host_core_version == 0x30)) {
-
- uint32 int_reg;
- uint32 max_count = 0;
-
- mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
- int_reg = mddi_host_reg_in(INT);
- while ((int_reg & 0x100000) == 0) {
- udelay(3);
- int_reg = mddi_host_reg_in(INT);
- if (++max_count > 100)
- break;
- }
- }
-#endif
-
- /* Get CRC error count */
- crc_errors = mddi_host_reg_in(REV_CRC_ERR);
- if (crc_errors != 0) {
- pmhctl->log_parms.rev_crc_cnt += crc_errors;
- pmhctl->stats.rev_crc_count += crc_errors;
- MDDI_MSG_ERR("!!! MDDI %d Reverse CRC Error(s) !!!\n",
- crc_errors);
-#ifndef T_MSM7500
- /* Clear CRC error count */
- mddi_host_reg_out(REV_CRC_ERR, 0x0000);
-#endif
- /* also issue an RTD to attempt recovery */
- pmhctl->rtd_counter = mddi_rtd_frequency;
- }
-
- pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
-
- MDDI_MSG_DEBUG("MDDI rev pkt cnt=%d, ptr=0x%x, RTD:0x%x\n",
- rev_packet_count,
- pmhctl->rev_ptr_curr - pmhctl->rev_ptr_start,
- pmhctl->rtd_value);
-
- if (rev_packet_count >= 1) {
- mddi_invalidate_cache_lines((uint32 *) pmhctl->rev_ptr_start,
- MDDI_REV_BUFFER_SIZE);
- }
- /* order the reads */
- dma_coherent_post_ops();
- for (i = 0; i < rev_packet_count; i++) {
- mddi_rev_packet_type *rev_pkt_ptr;
-
- mddi_read_rev_packet(rev_packet_data);
-
- rev_pkt_ptr = (mddi_rev_packet_type *) rev_packet_data;
-
- if (rev_pkt_ptr->packet_length > pmhctl->rev_pkt_size) {
- MDDI_MSG_ERR("!!!invalid packet size: %d\n",
- rev_pkt_ptr->packet_length);
- }
-
- MDDI_MSG_DEBUG("MDDI rev pkt 0x%x size 0x%x\n",
- rev_pkt_ptr->packet_type,
- rev_pkt_ptr->packet_length);
-
- /* Do whatever you want to do with the data based on the packet type */
- switch (rev_pkt_ptr->packet_type) {
- case 66: /* Client Capability */
- {
- mddi_client_capability_type
- *client_capability_pkt_ptr;
-
- client_capability_pkt_ptr =
- (mddi_client_capability_type *)
- rev_packet_data;
- MDDI_MSG_NOTICE
- ("Client Capability: Week=%d, Year=%d\n",
- client_capability_pkt_ptr->
- Week_of_Manufacture,
- client_capability_pkt_ptr->
- Year_of_Manufacture);
- memcpy((void *)&mddi_client_capability_pkt,
- (void *)rev_packet_data,
- sizeof(mddi_client_capability_type));
- pmhctl->log_parms.cli_cap_cnt++;
- }
- break;
-
- case 70: /* Display Status */
- {
- mddi_client_status_type *client_status_pkt_ptr;
-
- client_status_pkt_ptr =
- (mddi_client_status_type *) rev_packet_data;
- if ((client_status_pkt_ptr->crc_error_count !=
- 0)
- || (client_status_pkt_ptr->
- reverse_link_request != 0)) {
- MDDI_MSG_ERR
- ("Client Status: RevReq=%d, CrcErr=%d\n",
- client_status_pkt_ptr->
- reverse_link_request,
- client_status_pkt_ptr->
- crc_error_count);
- } else {
- MDDI_MSG_DEBUG
- ("Client Status: RevReq=%d, CrcErr=%d\n",
- client_status_pkt_ptr->
- reverse_link_request,
- client_status_pkt_ptr->
- crc_error_count);
- }
- pmhctl->log_parms.fwd_crc_cnt +=
- client_status_pkt_ptr->crc_error_count;
- pmhctl->stats.fwd_crc_count +=
- client_status_pkt_ptr->crc_error_count;
- pmhctl->log_parms.cli_stat_cnt++;
- }
- break;
-
- case 146: /* register access packet */
- {
- mddi_register_access_packet_type
- * regacc_pkt_ptr;
-
- regacc_pkt_ptr =
- (mddi_register_access_packet_type *)
- rev_packet_data;
-
- MDDI_MSG_DEBUG
- ("Reg Acc parse reg=0x%x, value=0x%x\n",
- regacc_pkt_ptr->register_address,
- regacc_pkt_ptr->register_data_list);
-
- /* Copy register value to location passed in */
- if (mddi_reg_read_value_ptr) {
-#if defined(T_MSM6280) && !defined(T_MSM7200)
- /* only least significant 16 bits are valid with 6280 */
- *mddi_reg_read_value_ptr =
- regacc_pkt_ptr->
- register_data_list & 0x0000ffff;
-#else
- *mddi_reg_read_value_ptr =
- regacc_pkt_ptr->register_data_list;
-#endif
- mddi_reg_read_successful = TRUE;
- mddi_reg_read_value_ptr = NULL;
- }
-
-#ifdef DEBUG_MDDIHOSTI
- if ((mddi_gpio.polling_enabled) &&
- (regacc_pkt_ptr->register_address ==
- mddi_gpio.polling_reg)) {
- /*
- * ToDo: need to call Linux GPIO call
- * here...
- */
- mddi_client_lcd_gpio_poll(
- regacc_pkt_ptr->register_data_list);
- }
-#endif
- pmhctl->log_parms.reg_read_cnt++;
- }
- break;
-
- default: /* any other packet */
- {
- uint16 hdlr;
-
- for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS;
- hdlr++) {
- if (mddi_rev_pkt_handler[hdlr].
- pkt_type ==
- rev_pkt_ptr->packet_type) {
- (*
- (mddi_rev_pkt_handler[hdlr].
- handler)) (rev_pkt_ptr);
- /* pmhctl->rev_state = MDDI_REV_IDLE; */
- break;
- }
- }
- if (hdlr >= MAX_MDDI_REV_HANDLERS)
- MDDI_MSG_ERR("MDDI unknown rev pkt\n");
- }
- break;
- }
- }
- if ((pmhctl->rev_ptr_curr + pmhctl->rev_pkt_size) >=
- (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE)) {
- pmhctl->rev_ptr_written = FALSE;
- }
-
- if (pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) {
- pmhctl->rev_state = MDDI_REV_IDLE;
- if (mddi_rev_user.waiting) {
- mddi_rev_user.waiting = FALSE;
- complete(&(mddi_rev_user.done_comp));
- } else if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
- MDDI_MSG_ERR
- ("Reverse Encap state, but no reg read in progress\n");
- } else {
- if ((!mddi_reg_read_successful) &&
- (mddi_reg_read_retry < mddi_reg_read_retry_max) &&
- (mddi_enable_reg_read_retry)) {
- /*
- * There is a race condition that can happen
- * where the reverse encapsulation message is
- * sent out by the MDDI host before the register
- * read packet is sent. As a work-around for
- * that problem we issue the reverse
- * encapsulation one more time before giving up.
- */
- if (mddi_enable_reg_read_retry_once)
- mddi_reg_read_retry =
- mddi_reg_read_retry_max;
- pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
- pmhctl->stats.reg_read_failure++;
- } else {
- uint16 reg_read_idx =
- pmhctl->llist_info.reg_read_idx;
-
- mddi_reg_read_retry = 0;
- if (pmhctl->llist_notify[reg_read_idx].waiting) {
- complete(&
- (pmhctl->
- llist_notify[reg_read_idx].
- done_comp));
- }
- pmhctl->llist_info.reg_read_idx =
- UNASSIGNED_INDEX;
- if (pmhctl->llist_notify[reg_read_idx].
- done_cb != NULL) {
- (*
- (pmhctl->llist_notify[reg_read_idx].
- done_cb)) ();
- }
- pmhctl->llist_notify[reg_read_idx].next_idx =
- UNASSIGNED_INDEX;
- pmhctl->llist_notify[reg_read_idx].in_use =
- FALSE;
- pmhctl->llist_notify[reg_read_idx].waiting =
- FALSE;
- pmhctl->llist_notify[reg_read_idx].done_cb =
- NULL;
- if (!mddi_reg_read_successful)
- pmhctl->stats.reg_read_failure++;
- }
- }
- } else if (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) {
-#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
- if (mddi_host_core_version == 0x28 ||
- mddi_host_core_version == 0x30) {
- mddi_host_reg_out(FIFO_ALLOC, 0x00);
- pmhctl->rev_ptr_written = TRUE;
- mddi_host_reg_out(REV_PTR,
- pmhctl->mddi_rev_ptr_write_val);
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
- mddi_host_reg_out(CMD, 0xC00);
- }
-#endif
-
- if (mddi_rev_user.waiting) {
- mddi_rev_user.waiting = FALSE;
- complete(&(mddi_rev_user.done_comp));
- }
- pmhctl->rev_state = MDDI_REV_IDLE;
- } else {
- pmhctl->rev_state = MDDI_REV_IDLE;
- }
-
- /* pmhctl->rev_state = MDDI_REV_IDLE; */
-
- /* Re-enable interrupt */
- mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL,
- MDDI_INT_REV_DATA_AVAIL);
-
-}
-
-static void mddi_issue_reverse_encapsulation(void)
-{
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
- /* Only issue a reverse encapsulation packet if:
- * 1) another reverse is not in progress (MDDI_REV_IDLE).
- * 2) a register read has been sent (MDDI_REV_REG_READ_SENT).
- * 3) forward is not in progress, because of a hw bug in client that
- * causes forward crc errors on packet immediately after rev encap.
- */
- if (((pmhctl->rev_state == MDDI_REV_IDLE) ||
- (pmhctl->rev_state == MDDI_REV_REG_READ_SENT)) &&
- (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
- (!mdp_in_processing)) {
- uint32 mddi_command = MDDI_CMD_SEND_REV_ENCAP;
-
- if ((pmhctl->rev_state == MDDI_REV_REG_READ_SENT) ||
- (mddi_rev_encap_user_request == TRUE)) {
- mddi_host_enable_io_clock();
- if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
- /* need to wake up link before issuing rev encap command */
- MDDI_MSG_DEBUG("wake up link!\n");
- pmhctl->link_state = MDDI_LINK_ACTIVATING;
- mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
- } else {
- if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
- MDDI_MSG_DEBUG
- ("mddi sending RTD command!\n");
- mddi_host_reg_out(CMD,
- MDDI_CMD_SEND_RTD);
- pmhctl->rtd_counter = 0;
- pmhctl->log_parms.rtd_cnt++;
- }
- if (pmhctl->rev_state != MDDI_REV_REG_READ_SENT) {
- /* this is generic reverse request by user, so
- * reset the waiting flag. */
- mddi_rev_encap_user_request = FALSE;
- }
- /* link is active so send reverse encap to get register read results */
- pmhctl->rev_state = MDDI_REV_ENCAP_ISSUED;
- mddi_command = MDDI_CMD_SEND_REV_ENCAP;
- MDDI_MSG_DEBUG("sending rev encap!\n");
- }
- } else
- if ((pmhctl->client_status_cnt >=
- mddi_client_status_frequency)
- || mddi_client_capability_request) {
- mddi_host_enable_io_clock();
- if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
- /* only wake up the link if it client status is overdue */
- if ((pmhctl->client_status_cnt >=
- (mddi_client_status_frequency * 2))
- || mddi_client_capability_request) {
- /* need to wake up link before issuing rev encap command */
- MDDI_MSG_DEBUG("wake up link!\n");
- pmhctl->link_state =
- MDDI_LINK_ACTIVATING;
- mddi_host_reg_out(CMD,
- MDDI_CMD_LINK_ACTIVE);
- }
- } else {
- if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
- MDDI_MSG_DEBUG
- ("mddi sending RTD command!\n");
- mddi_host_reg_out(CMD,
- MDDI_CMD_SEND_RTD);
- pmhctl->rtd_counter = 0;
- pmhctl->log_parms.rtd_cnt++;
- }
- /* periodically get client status */
- MDDI_MSG_DEBUG
- ("mddi sending rev enc! (get status)\n");
- if (mddi_client_capability_request) {
- pmhctl->rev_state =
- MDDI_REV_CLIENT_CAP_ISSUED;
- mddi_command = MDDI_CMD_GET_CLIENT_CAP;
- mddi_client_capability_request = FALSE;
- } else {
- pmhctl->rev_state =
- MDDI_REV_STATUS_REQ_ISSUED;
- pmhctl->client_status_cnt = 0;
- mddi_command =
- MDDI_CMD_GET_CLIENT_STATUS;
- }
- }
- }
- if ((pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) ||
- (pmhctl->rev_state == MDDI_REV_STATUS_REQ_ISSUED) ||
- (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED)) {
- pmhctl->int_type.rev_encap_count++;
-#if defined(T_MSM6280) && !defined(T_MSM7200)
- mddi_rev_pointer_written = TRUE;
- mddi_host_reg_out(REV_PTR, mddi_rev_ptr_write_val);
- mddi_rev_ptr_curr = mddi_rev_ptr_start;
- /* force new rev ptr command */
- mddi_host_reg_out(CMD, 0xC00);
-#else
- if (!pmhctl->rev_ptr_written) {
- MDDI_MSG_DEBUG("writing reverse pointer!\n");
- pmhctl->rev_ptr_written = TRUE;
-#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
- if ((pmhctl->rev_state ==
- MDDI_REV_CLIENT_CAP_ISSUED) &&
- (mddi_host_core_version == 0x28 ||
- mddi_host_core_version == 0x30)) {
- pmhctl->rev_ptr_written = FALSE;
- mddi_host_reg_out(FIFO_ALLOC, 0x02);
- } else
- mddi_host_reg_out(REV_PTR,
- pmhctl->
- mddi_rev_ptr_write_val);
-#else
- mddi_host_reg_out(REV_PTR,
- pmhctl->
- mddi_rev_ptr_write_val);
-#endif
- }
-#endif
- if (mddi_debug_clear_rev_data) {
- uint16 i;
- for (i = 0; i < MDDI_MAX_REV_DATA_SIZE / 4; i++)
- pmhctl->rev_data_buf[i] = 0xdddddddd;
- /* clean cache */
- mddi_flush_cache_lines(pmhctl->rev_data_buf,
- MDDI_MAX_REV_DATA_SIZE);
- }
-
- /* send reverse encapsulation to get needed data */
- mddi_host_reg_out(CMD, mddi_command);
- }
- }
-
-}
-
-static void mddi_process_client_initiated_wakeup(void)
-{
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- /* Disable MDDI_INT Interrupt, we detect client initiated wakeup one
- * time for each entry into hibernation */
- mddi_host_reg_outm(INTEN, MDDI_INT_MDDI_IN, 0);
-
- if (host_idx == MDDI_HOST_PRIM) {
- if (mddi_vsync_detect_enabled) {
- mddi_host_enable_io_clock();
-#ifndef MDDI_HOST_DISP_LISTEN
- /* issue command to bring up link */
- /* need to do this to clear the vsync condition */
- if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
- pmhctl->link_state = MDDI_LINK_ACTIVATING;
- mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
- }
-#endif
- /*
- * Indicate to client specific code that vsync was
- * enabled, and we did not detect a client initiated
- * wakeup. The client specific handler can clear the
- * condition if necessary to prevent subsequent
- * client initiated wakeups.
- */
- mddi_client_lcd_vsync_detected(TRUE);
- pmhctl->log_parms.vsync_response_cnt++;
- MDDI_MSG_NOTICE("MDDI_INT_IN condition\n");
-
- }
- }
-
- if (mddi_gpio.polling_enabled) {
- mddi_host_enable_io_clock();
- /* check interrupt status now */
- (void)mddi_queue_register_read_int(mddi_gpio.polling_reg,
- &mddi_gpio.polling_val);
- }
-}
-#endif /* FEATURE_MDDI_DISABLE_REVERSE */
-
-static void mddi_host_isr(void)
-{
- uint32 int_reg, int_en;
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- uint32 status_reg;
-#endif
- mddi_host_type host_idx = mddi_curr_host;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if (!MDDI_HOST_IS_HCLK_ON) {
- MDDI_HOST_ENABLE_HCLK;
- MDDI_MSG_DEBUG("HCLK disabled, but isr is firing\n");
- }
- int_reg = mddi_host_reg_in(INT);
- int_en = mddi_host_reg_in(INTEN);
- pmhctl->saved_int_reg = int_reg;
- pmhctl->saved_int_en = int_en;
- int_reg = int_reg & int_en;
- pmhctl->int_type.count++;
-
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- status_reg = mddi_host_reg_in(STAT);
-
- if ((int_reg & MDDI_INT_MDDI_IN) ||
- ((int_en & MDDI_INT_MDDI_IN) &&
- ((int_reg == 0) || (status_reg & MDDI_STAT_CLIENT_WAKEUP_REQ)))) {
- /*
- * The MDDI_IN condition will clear itself, and so it is
- * possible that MDDI_IN was the reason for the isr firing,
- * even though the interrupt register does not have the
- * MDDI_IN bit set. To check if this was the case we need to
- * look at the status register bit that signifies a client
- * initiated wakeup. If the status register bit is set, as well
- * as the MDDI_IN interrupt enabled, then we treat this as a
- * client initiated wakeup.
- */
- if (int_reg & MDDI_INT_MDDI_IN)
- pmhctl->int_type.in_count++;
- mddi_process_client_initiated_wakeup();
- }
-#endif
-
- if (int_reg & MDDI_INT_LINK_STATE_CHANGES) {
- pmhctl->int_type.state_change_count++;
- mddi_report_state_change(int_reg);
- }
-
- if (int_reg & MDDI_INT_PRI_LINK_LIST_DONE) {
- pmhctl->int_type.ll_done_count++;
- mddi_process_link_list_done();
- }
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (int_reg & MDDI_INT_REV_DATA_AVAIL) {
- pmhctl->int_type.rev_avail_count++;
- mddi_process_rev_packets();
- }
-#endif
-
- if (int_reg & MDDI_INT_ERROR_CONDITIONS) {
- pmhctl->int_type.error_count++;
- mddi_report_errors(int_reg);
-
- mddi_host_reg_out(INT, int_reg & MDDI_INT_ERROR_CONDITIONS);
- }
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- mddi_issue_reverse_encapsulation();
-
- if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
- (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED))
-#endif
- /* don't want simultaneous reverse and forward with Eagle */
- mddi_queue_forward_linked_list();
-
- if (int_reg & MDDI_INT_NO_CMD_PKTS_PEND) {
- /* this interrupt is used to kick the isr when hibernation is disabled */
- mddi_host_reg_outm(INTEN, MDDI_INT_NO_CMD_PKTS_PEND, 0);
- }
-
- if ((!mddi_host_mdp_active_flag) &&
- (!mddi_vsync_detect_enabled) &&
- (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
- (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
- (pmhctl->rev_state == MDDI_REV_IDLE)) {
- if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
- mddi_host_disable_io_clock();
- mddi_host_disable_hclk();
- }
-#ifdef FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION
- else if ((pmhctl->link_state == MDDI_LINK_ACTIVE) &&
- (!pmhctl->disable_hibernation)) {
- mddi_host_reg_out(CMD, MDDI_CMD_POWERDOWN);
- }
-#endif
- }
-}
-
-static void mddi_host_isr_primary(void)
-{
- mddi_curr_host = MDDI_HOST_PRIM;
- mddi_host_isr();
-}
-
-irqreturn_t mddi_pmdh_isr_proxy(int irq, void *ptr)
-{
- mddi_host_isr_primary();
- return IRQ_HANDLED;
-}
-
-static void mddi_host_isr_external(void)
-{
- mddi_curr_host = MDDI_HOST_EXT;
- mddi_host_isr();
- mddi_curr_host = MDDI_HOST_PRIM;
-}
-
-irqreturn_t mddi_emdh_isr_proxy(int irq, void *ptr)
-{
- mddi_host_isr_external();
- return IRQ_HANDLED;
-}
-
-static void mddi_host_initialize_registers(mddi_host_type host_idx)
-{
- uint32 pad_reg_val;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
- return;
-
- /* turn on HCLK to MDDI host core */
- mddi_host_enable_hclk();
-
- /* MDDI Reset command */
- mddi_host_reg_out(CMD, MDDI_CMD_RESET);
-
- /* Version register (= 0x01) */
- mddi_host_reg_out(VERSION, 0x0001);
-
- /* Bytes per subframe register */
- mddi_host_reg_out(BPS, MDDI_HOST_BYTES_PER_SUBFRAME);
-
- /* Subframes per media frames register (= 0x03) */
- mddi_host_reg_out(SPM, 0x0003);
-
- /* Turn Around 1 register (= 0x05) */
- mddi_host_reg_out(TA1_LEN, 0x0005);
-
- /* Turn Around 2 register (= 0x0C) */
- mddi_host_reg_out(TA2_LEN, MDDI_HOST_TA2_LEN);
-
- /* Drive hi register (= 0x96) */
- mddi_host_reg_out(DRIVE_HI, 0x0096);
-
- /* Drive lo register (= 0x32) */
- mddi_host_reg_out(DRIVE_LO, 0x0032);
-
- /* Display wakeup count register (= 0x3c) */
- mddi_host_reg_out(DISP_WAKE, 0x003c);
-
- /* Reverse Rate Divisor register (= 0x2) */
- mddi_host_reg_out(REV_RATE_DIV, MDDI_HOST_REV_RATE_DIV);
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- /* Reverse Pointer Size */
- mddi_host_reg_out(REV_SIZE, MDDI_REV_BUFFER_SIZE);
-
- /* Rev Encap Size */
- mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
-#endif
-
- /* Periodic Rev Encap */
- /* don't send periodically */
- mddi_host_reg_out(CMD, MDDI_CMD_PERIODIC_REV_ENCAP);
-
- pad_reg_val = mddi_host_reg_in(PAD_CTL);
- if (pad_reg_val == 0) {
- /* If we are turning on band gap, need to wait 5us before turning
- * on the rest of the PAD */
- mddi_host_reg_out(PAD_CTL, 0x08000);
- udelay(5);
- }
-#ifdef T_MSM7200
- /* Recommendation from PAD hw team */
- mddi_host_reg_out(PAD_CTL, 0xa850a);
-#else
- /* Recommendation from PAD hw team */
- mddi_host_reg_out(PAD_CTL, 0xa850f);
-#endif
-
-#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
- mddi_host_reg_out(PAD_IO_CTL, 0x00320000);
- mddi_host_reg_out(PAD_CAL, 0x00220020);
-#endif
-
- mddi_host_core_version = mddi_host_reg_inm(CORE_VER, 0xffff);
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (mddi_host_core_version >= 8)
- mddi_rev_ptr_workaround = FALSE;
- pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
-#endif
-
- if ((mddi_host_core_version > 8) && (mddi_host_core_version < 0x19))
- mddi_host_reg_out(TEST, 0x2);
-
- /* Need an even number for counts */
- mddi_host_reg_out(DRIVER_START_CNT, 0x60006);
-
-#ifndef T_MSM7500
- /* Setup defaults for MDP related register */
- mddi_host_reg_out(MDP_VID_FMT_DES, 0x5666);
- mddi_host_reg_out(MDP_VID_PIX_ATTR, 0x00C3);
- mddi_host_reg_out(MDP_VID_CLIENTID, 0);
-#endif
-
- /* automatically hibernate after 1 empty subframe */
- if (pmhctl->disable_hibernation)
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
- else
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
-
- /* Bring up link if display (client) requests it */
-#ifdef MDDI_HOST_DISP_LISTEN
- mddi_host_reg_out(CMD, MDDI_CMD_DISP_LISTEN);
-#else
- mddi_host_reg_out(CMD, MDDI_CMD_DISP_IGNORE);
-#endif
-
-}
-
-void mddi_host_configure_interrupts(mddi_host_type host_idx, boolean enable)
-{
- unsigned long flags;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
-
- /* turn on HCLK to MDDI host core if it has been disabled */
- mddi_host_enable_hclk();
- /* Clear MDDI Interrupt enable reg */
- mddi_host_reg_out(INTEN, 0);
-
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- if (enable) {
- pmhctl->driver_state = MDDI_DRIVER_ENABLED;
-
- if (host_idx == MDDI_HOST_PRIM) {
- if (request_irq
- (INT_MDDI_PRI, mddi_pmdh_isr_proxy, IRQF_DISABLED,
- "PMDH", 0) != 0)
- printk(KERN_ERR
- "a mddi: unable to request_irq\n");
- else
- int_mddi_pri_flag = TRUE;
- } else {
- if (request_irq
- (INT_MDDI_EXT, mddi_emdh_isr_proxy, IRQF_DISABLED,
- "EMDH", 0) != 0)
- printk(KERN_ERR
- "b mddi: unable to request_irq\n");
- else
- int_mddi_ext_flag = TRUE;
- }
-
- /* Set MDDI Interrupt enable reg -- Enable Reverse data avail */
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- mddi_host_reg_out(INTEN,
- MDDI_INT_ERROR_CONDITIONS |
- MDDI_INT_LINK_STATE_CHANGES);
-#else
- /* Reverse Pointer register */
- pmhctl->rev_ptr_written = FALSE;
-
- mddi_host_reg_out(INTEN,
- MDDI_INT_REV_DATA_AVAIL |
- MDDI_INT_ERROR_CONDITIONS |
- MDDI_INT_LINK_STATE_CHANGES);
- pmhctl->rtd_counter = mddi_rtd_frequency;
- pmhctl->client_status_cnt = 0;
-#endif
- } else {
- if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
- pmhctl->driver_state = MDDI_DRIVER_DISABLED;
- }
-
-}
-
-static void mddi_host_powerup(mddi_host_type host_idx)
-{
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if (pmhctl->link_state != MDDI_LINK_DISABLED)
- return;
-
- /* enable IO_CLK and hclk to MDDI host core */
- mddi_host_enable_io_clock();
-
- mddi_host_initialize_registers(host_idx);
- mddi_host_configure_interrupts(host_idx, TRUE);
-
- pmhctl->link_state = MDDI_LINK_ACTIVATING;
-
- /* Link activate command */
- mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
-
-#ifdef CLKRGM_MDDI_IO_CLOCK_IN_MHZ
- MDDI_MSG_NOTICE("MDDI Host: Activating Link %d Mbps\n",
- CLKRGM_MDDI_IO_CLOCK_IN_MHZ * 2);
-#else
- MDDI_MSG_NOTICE("MDDI Host: Activating Link\n");
-#endif
-
- /* Initialize the timer */
- if (host_idx == MDDI_HOST_PRIM)
- mddi_host_timer_service(0);
-}
-
-void mddi_host_init(mddi_host_type host_idx)
-/* Write out the MDDI configuration registers */
-{
- static boolean initialized = FALSE;
- mddi_host_cntl_type *pmhctl;
-
- if (host_idx >= MDDI_NUM_HOST_CORES) {
- MDDI_MSG_ERR("Invalid host core index\n");
- return;
- }
-
- if (!initialized) {
- uint16 idx;
- mddi_host_type host;
- for (host = MDDI_HOST_PRIM; host < MDDI_NUM_HOST_CORES; host++) {
- pmhctl = &(mhctl[host]);
- initialized = TRUE;
-
- pmhctl->llist_ptr =
- dma_alloc_coherent(NULL, MDDI_LLIST_POOL_SIZE,
- &(pmhctl->llist_dma_addr),
- GFP_KERNEL);
- pmhctl->llist_dma_ptr =
- (mddi_linked_list_type *) (void *)pmhctl->
- llist_dma_addr;
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- pmhctl->rev_data_buf = NULL;
- if (pmhctl->llist_ptr == NULL)
-#else
- mddi_rev_user.waiting = FALSE;
- init_completion(&(mddi_rev_user.done_comp));
- pmhctl->rev_data_buf =
- dma_alloc_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
- &(pmhctl->rev_data_dma_addr),
- GFP_KERNEL);
- if ((pmhctl->llist_ptr == NULL)
- || (pmhctl->rev_data_buf == NULL))
-#endif
- {
- MDDI_MSG_CRIT
- ("unable to alloc non-cached memory\n");
- }
- llist_extern[host] = pmhctl->llist_ptr;
- llist_dma_extern[host] = pmhctl->llist_dma_ptr;
- llist_extern_notify[host] = pmhctl->llist_notify;
-
- for (idx = 0; idx < UNASSIGNED_INDEX; idx++) {
- init_completion(&
- (pmhctl->llist_notify[idx].
- done_comp));
- }
- init_completion(&(pmhctl->mddi_llist_avail_comp));
- spin_lock_init(&mddi_host_spin_lock);
- pmhctl->mddi_waiting_for_llist_avail = FALSE;
- pmhctl->mddi_rev_ptr_write_val =
- (uint32) (void *)(pmhctl->rev_data_dma_addr);
- pmhctl->rev_ptr_start = (void *)pmhctl->rev_data_buf;
-
- pmhctl->rev_pkt_size = MDDI_DEFAULT_REV_PKT_SIZE;
- pmhctl->rev_state = MDDI_REV_IDLE;
-#ifdef IMAGE_MODEM_PROC
- /* assume hibernation state is last state from APPS proc, so that
- * we don't reinitialize the host core */
- pmhctl->link_state = MDDI_LINK_HIBERNATING;
-#else
- pmhctl->link_state = MDDI_LINK_DISABLED;
-#endif
- pmhctl->driver_state = MDDI_DRIVER_DISABLED;
- pmhctl->disable_hibernation = FALSE;
-
- /* initialize llist variables */
- pmhctl->llist_info.transmitting_start_idx =
- UNASSIGNED_INDEX;
- pmhctl->llist_info.transmitting_end_idx =
- UNASSIGNED_INDEX;
- pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
- pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
- pmhctl->llist_info.reg_read_idx = UNASSIGNED_INDEX;
- pmhctl->llist_info.next_free_idx =
- MDDI_FIRST_DYNAMIC_LLIST_IDX;
- pmhctl->llist_info.reg_read_waiting = FALSE;
-
- mddi_vsync_detect_enabled = FALSE;
- mddi_gpio.polling_enabled = FALSE;
-
- pmhctl->int_type.count = 0;
- pmhctl->int_type.in_count = 0;
- pmhctl->int_type.disp_req_count = 0;
- pmhctl->int_type.state_change_count = 0;
- pmhctl->int_type.ll_done_count = 0;
- pmhctl->int_type.rev_avail_count = 0;
- pmhctl->int_type.error_count = 0;
- pmhctl->int_type.rev_encap_count = 0;
- pmhctl->int_type.llist_ptr_write_1 = 0;
- pmhctl->int_type.llist_ptr_write_2 = 0;
-
- pmhctl->stats.fwd_crc_count = 0;
- pmhctl->stats.rev_crc_count = 0;
- pmhctl->stats.pri_underflow = 0;
- pmhctl->stats.sec_underflow = 0;
- pmhctl->stats.rev_overflow = 0;
- pmhctl->stats.pri_overwrite = 0;
- pmhctl->stats.sec_overwrite = 0;
- pmhctl->stats.rev_overwrite = 0;
- pmhctl->stats.dma_failure = 0;
- pmhctl->stats.rtd_failure = 0;
- pmhctl->stats.reg_read_failure = 0;
-#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
- pmhctl->stats.pri_underrun_detected = 0;
-#endif
-
- pmhctl->log_parms.rtd_cnt = 0;
- pmhctl->log_parms.rev_enc_cnt = 0;
- pmhctl->log_parms.vid_cnt = 0;
- pmhctl->log_parms.reg_acc_cnt = 0;
- pmhctl->log_parms.cli_stat_cnt = 0;
- pmhctl->log_parms.cli_cap_cnt = 0;
- pmhctl->log_parms.reg_read_cnt = 0;
- pmhctl->log_parms.link_active_cnt = 0;
- pmhctl->log_parms.link_hibernate_cnt = 0;
- pmhctl->log_parms.fwd_crc_cnt = 0;
- pmhctl->log_parms.rev_crc_cnt = 0;
- pmhctl->log_parms.vsync_response_cnt = 0;
-
- prev_parms[host_idx] = pmhctl->log_parms;
- mddi_client_capability_pkt.packet_length = 0;
- }
-
-#ifndef T_MSM7500
- /* tell clock driver we are user of this PLL */
- MDDI_HOST_ENABLE_IO_CLOCK;
-#endif
- }
-
- mddi_host_powerup(host_idx);
- pmhctl = &(mhctl[host_idx]);
-}
-
-#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
-static uint32 mddi_client_id;
-
-uint32 mddi_get_client_id(void)
-{
-
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- mddi_host_type host_idx = MDDI_HOST_PRIM;
- static boolean client_detection_try = FALSE;
- mddi_host_cntl_type *pmhctl;
- unsigned long flags;
- uint16 saved_rev_pkt_size;
-
- if (!client_detection_try) {
- /* Toshiba display requires larger drive_lo value */
- mddi_host_reg_out(DRIVE_LO, 0x0050);
-
- pmhctl = &(mhctl[MDDI_HOST_PRIM]);
-
- saved_rev_pkt_size = pmhctl->rev_pkt_size;
-
- /* Increase Rev Encap Size */
- pmhctl->rev_pkt_size = MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE;
- mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
-
- /* disable hibernation temporarily */
- if (!pmhctl->disable_hibernation)
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
-
- mddi_rev_user.waiting = TRUE;
- INIT_COMPLETION(mddi_rev_user.done_comp);
-
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
-
- /* turn on clock(s), if they have been disabled */
- mddi_host_enable_hclk();
- mddi_host_enable_io_clock();
-
- mddi_client_capability_request = TRUE;
-
- if (pmhctl->rev_state == MDDI_REV_IDLE) {
- /* attempt to send the reverse encapsulation now */
- mddi_issue_reverse_encapsulation();
- }
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- wait_for_completion_killable(&(mddi_rev_user.done_comp));
-
- /* Set Rev Encap Size back to its original value */
- pmhctl->rev_pkt_size = saved_rev_pkt_size;
- mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
-
- /* reenable auto-hibernate */
- if (!pmhctl->disable_hibernation)
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
-
- mddi_host_reg_out(DRIVE_LO, 0x0032);
- client_detection_try = TRUE;
-
- mddi_client_id = (mddi_client_capability_pkt.Mfr_Name<<16) |
- mddi_client_capability_pkt.Product_Code;
-
- if (!mddi_client_id)
- mddi_disable(1);
- }
-
-#if 0
- switch (mddi_client_capability_pkt.Mfr_Name) {
- case 0x4474:
- if ((mddi_client_capability_pkt.Product_Code != 0x8960) &&
- (target == DISPLAY_1)) {
- ret = PRISM_WVGA;
- }
- break;
-
- case 0xD263:
- if (target == DISPLAY_1)
- ret = TOSHIBA_VGA_PRIM;
- else if (target == DISPLAY_2)
- ret = TOSHIBA_QCIF_SECD;
- break;
-
- case 0:
- if (mddi_client_capability_pkt.Product_Code == 0x8835) {
- if (target == DISPLAY_1)
- ret = SHARP_QVGA_PRIM;
- else if (target == DISPLAY_2)
- ret = SHARP_128x128_SECD;
- }
- break;
-
- default:
- break;
- }
-
- if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM)
- && (ret != TOSHIBA_QCIF_SECD)) {
- /* Not a Toshiba display, so change drive_lo back to default value */
- mddi_host_reg_out(DRIVE_LO, 0x0032);
- }
-#endif
-
-#endif
-
- return mddi_client_id;
-}
-#endif
-
-void mddi_host_powerdown(mddi_host_type host_idx)
-{
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if (host_idx >= MDDI_NUM_HOST_CORES) {
- MDDI_MSG_ERR("Invalid host core index\n");
- return;
- }
-
- if (pmhctl->driver_state == MDDI_DRIVER_RESET) {
- return;
- }
-
- if (host_idx == MDDI_HOST_PRIM) {
- /* disable timer */
- del_timer(&mddi_host_timer);
- }
-
- mddi_host_configure_interrupts(host_idx, FALSE);
-
- /* turn on HCLK to MDDI host core if it has been disabled */
- mddi_host_enable_hclk();
-
- /* MDDI Reset command */
- mddi_host_reg_out(CMD, MDDI_CMD_RESET);
-
- /* Pad Control Register */
- mddi_host_reg_out(PAD_CTL, 0x0);
-
- /* disable IO_CLK and hclk to MDDI host core */
- mddi_host_disable_io_clock();
- mddi_host_disable_hclk();
-
- pmhctl->link_state = MDDI_LINK_DISABLED;
- pmhctl->driver_state = MDDI_DRIVER_RESET;
-
- MDDI_MSG_NOTICE("MDDI Host: Disabling Link\n");
-
-}
-
-uint16 mddi_get_next_free_llist_item(mddi_host_type host_idx, boolean wait)
-{
- unsigned long flags;
- uint16 ret_idx;
- boolean forced_wait = FALSE;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- ret_idx = pmhctl->llist_info.next_free_idx;
-
- pmhctl->llist_info.next_free_idx++;
- if (pmhctl->llist_info.next_free_idx >= MDDI_NUM_DYNAMIC_LLIST_ITEMS)
- pmhctl->llist_info.next_free_idx = MDDI_FIRST_DYNAMIC_LLIST_IDX;
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
- if (pmhctl->llist_notify[ret_idx].in_use) {
- if (!wait) {
- pmhctl->llist_info.next_free_idx = ret_idx;
- ret_idx = UNASSIGNED_INDEX;
- } else {
- forced_wait = TRUE;
- INIT_COMPLETION(pmhctl->mddi_llist_avail_comp);
- }
- }
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- if (forced_wait) {
- wait_for_completion_killable(&
- (pmhctl->
- mddi_llist_avail_comp));
- MDDI_MSG_ERR("task waiting on mddi llist item\n");
- }
-
- if (ret_idx != UNASSIGNED_INDEX) {
- pmhctl->llist_notify[ret_idx].waiting = FALSE;
- pmhctl->llist_notify[ret_idx].done_cb = NULL;
- pmhctl->llist_notify[ret_idx].in_use = TRUE;
- pmhctl->llist_notify[ret_idx].next_idx = UNASSIGNED_INDEX;
- }
-
- return ret_idx;
-}
-
-uint16 mddi_get_reg_read_llist_item(mddi_host_type host_idx, boolean wait)
-{
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- MDDI_MSG_CRIT("No reverse link available\n");
- (void)wait;
- return FALSE;
-#else
- unsigned long flags;
- uint16 ret_idx;
- boolean error = FALSE;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
- if (pmhctl->llist_info.reg_read_idx != UNASSIGNED_INDEX) {
- /* need to block here or is this an error condition? */
- error = TRUE;
- ret_idx = UNASSIGNED_INDEX;
- }
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- if (!error) {
- ret_idx = pmhctl->llist_info.reg_read_idx =
- mddi_get_next_free_llist_item(host_idx, wait);
- /* clear the reg_read_waiting flag */
- pmhctl->llist_info.reg_read_waiting = FALSE;
- }
-
- if (error)
- MDDI_MSG_ERR("***** Reg read still in progress! ****\n");
- return ret_idx;
-#endif
-
-}
-
-void mddi_queue_forward_packets(uint16 first_llist_idx,
- uint16 last_llist_idx,
- boolean wait,
- mddi_llist_done_cb_type llist_done_cb,
- mddi_host_type host_idx)
-{
- unsigned long flags;
- mddi_linked_list_type *llist;
- mddi_linked_list_type *llist_dma;
- mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
-
- if ((first_llist_idx >= UNASSIGNED_INDEX) ||
- (last_llist_idx >= UNASSIGNED_INDEX)) {
- MDDI_MSG_ERR("MDDI queueing invalid linked list\n");
- return;
- }
-
- if (pmhctl->link_state == MDDI_LINK_DISABLED)
- MDDI_MSG_CRIT("MDDI host powered down!\n");
-
- llist = pmhctl->llist_ptr;
- llist_dma = pmhctl->llist_dma_ptr;
-
- /* clean cache so MDDI host can read data */
- memory_barrier();
-
- pmhctl->llist_notify[last_llist_idx].waiting = wait;
- if (wait)
- INIT_COMPLETION(pmhctl->llist_notify[last_llist_idx].done_comp);
- pmhctl->llist_notify[last_llist_idx].done_cb = llist_done_cb;
-
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
-
- if ((pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
- (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
- (pmhctl->rev_state == MDDI_REV_IDLE)) {
- /* no packets are currently transmitting */
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
- /* This is the special case where the packet is a register read. */
- pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
- mddi_reg_read_retry = 0;
- /* mddi_rev_reg_read_attempt = 1; */
- }
-#endif
- /* assign transmitting index values */
- pmhctl->llist_info.transmitting_start_idx = first_llist_idx;
- pmhctl->llist_info.transmitting_end_idx = last_llist_idx;
-
- /* turn on clock(s), if they have been disabled */
- mddi_host_enable_hclk();
- mddi_host_enable_io_clock();
- pmhctl->int_type.llist_ptr_write_1++;
- /* Write to primary pointer register */
- dma_coherent_pre_ops();
- mddi_host_reg_out(PRI_PTR, &llist_dma[first_llist_idx]);
-
- /* enable interrupt when complete */
- mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
- MDDI_INT_PRI_LINK_LIST_DONE);
-
- } else if (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) {
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
- /*
- * we have a register read to send but need to wait
- * for current reverse activity to end or there are
- * packets currently transmitting
- */
- /* mddi_rev_reg_read_attempt = 0; */
- pmhctl->llist_info.reg_read_waiting = TRUE;
- }
-#endif
-
- /* assign waiting index values */
- pmhctl->llist_info.waiting_start_idx = first_llist_idx;
- pmhctl->llist_info.waiting_end_idx = last_llist_idx;
- } else {
- uint16 prev_end_idx = pmhctl->llist_info.waiting_end_idx;
-#ifndef FEATURE_MDDI_DISABLE_REVERSE
- if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
- /*
- * we have a register read to send but need to wait
- * for current reverse activity to end or there are
- * packets currently transmitting
- */
- /* mddi_rev_reg_read_attempt = 0; */
- pmhctl->llist_info.reg_read_waiting = TRUE;
- }
-#endif
-
- llist = pmhctl->llist_ptr;
-
- /* clear end flag in previous last packet */
- llist[prev_end_idx].link_controller_flags = 0;
- pmhctl->llist_notify[prev_end_idx].next_idx = first_llist_idx;
-
- /* set the next_packet_pointer of the previous last packet */
- llist[prev_end_idx].next_packet_pointer =
- (void *)(&llist_dma[first_llist_idx]);
-
- /* clean cache so MDDI host can read data */
- memory_barrier();
-
- /* assign new waiting last index value */
- pmhctl->llist_info.waiting_end_idx = last_llist_idx;
- }
-
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
-}
-
-void mddi_host_write_pix_attr_reg(uint32 value)
-{
- (void)value;
-}
-
-void mddi_queue_reverse_encapsulation(boolean wait)
-{
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- MDDI_MSG_CRIT("No reverse link available\n");
- (void)wait;
-#else
- unsigned long flags;
- boolean error = FALSE;
- mddi_host_type host_idx = MDDI_HOST_PRIM;
- mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
-
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
-
- /* turn on clock(s), if they have been disabled */
- mddi_host_enable_hclk();
- mddi_host_enable_io_clock();
-
- if (wait) {
- if (!mddi_rev_user.waiting) {
- mddi_rev_user.waiting = TRUE;
- INIT_COMPLETION(mddi_rev_user.done_comp);
- } else
- error = TRUE;
- }
- mddi_rev_encap_user_request = TRUE;
-
- if (pmhctl->rev_state == MDDI_REV_IDLE) {
- /* attempt to send the reverse encapsulation now */
- mddi_host_type orig_host_idx = mddi_curr_host;
- mddi_curr_host = host_idx;
- mddi_issue_reverse_encapsulation();
- mddi_curr_host = orig_host_idx;
- }
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- if (error) {
- MDDI_MSG_ERR("Reverse Encap request already in progress\n");
- } else if (wait)
- wait_for_completion_killable(&(mddi_rev_user.done_comp));
-#endif
-}
-
-/* ISR to be executed */
-boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type)
-{
-#ifdef FEATURE_MDDI_DISABLE_REVERSE
- MDDI_MSG_CRIT("No reverse link available\n");
- (void)handler;
- (void)pkt_type;
- return (FALSE);
-#else
- unsigned long flags;
- uint16 hdlr;
- boolean handler_set = FALSE;
- boolean overwrite = FALSE;
- mddi_host_type host_idx = MDDI_HOST_PRIM;
- mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
-
- /* Disable interrupts */
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
-
- for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
- if (mddi_rev_pkt_handler[hdlr].pkt_type == pkt_type) {
- mddi_rev_pkt_handler[hdlr].handler = handler;
- if (handler == NULL) {
- /* clearing handler from table */
- mddi_rev_pkt_handler[hdlr].pkt_type =
- INVALID_PKT_TYPE;
- handler_set = TRUE;
- if (pkt_type == 0x10) { /* video stream packet */
- /* ensure HCLK on to MDDI host core before register write */
- mddi_host_enable_hclk();
- /* No longer getting video, so reset rev encap size to default */
- pmhctl->rev_pkt_size =
- MDDI_DEFAULT_REV_PKT_SIZE;
- mddi_host_reg_out(REV_ENCAP_SZ,
- pmhctl->rev_pkt_size);
- }
- } else {
- /* already a handler for this packet */
- overwrite = TRUE;
- }
- break;
- }
- }
- if ((hdlr >= MAX_MDDI_REV_HANDLERS) && (handler != NULL)) {
- /* assigning new handler */
- for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
- if (mddi_rev_pkt_handler[hdlr].pkt_type ==
- INVALID_PKT_TYPE) {
- if ((pkt_type == 0x10) && /* video stream packet */
- (pmhctl->rev_pkt_size <
- MDDI_VIDEO_REV_PKT_SIZE)) {
- /* ensure HCLK on to MDDI host core before register write */
- mddi_host_enable_hclk();
- /* Increase Rev Encap Size */
- pmhctl->rev_pkt_size =
- MDDI_VIDEO_REV_PKT_SIZE;
- mddi_host_reg_out(REV_ENCAP_SZ,
- pmhctl->rev_pkt_size);
- }
- mddi_rev_pkt_handler[hdlr].handler = handler;
- mddi_rev_pkt_handler[hdlr].pkt_type = pkt_type;
- handler_set = TRUE;
- break;
- }
- }
- }
-
- /* Restore interrupts */
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
-
- if (overwrite)
- MDDI_MSG_ERR("Overwriting previous rev packet handler\n");
-
- return handler_set;
-
-#endif
-} /* mddi_set_rev_handler */
-
-void mddi_host_disable_hibernation(boolean disable)
-{
- mddi_host_type host_idx = MDDI_HOST_PRIM;
- mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
-
- if (disable) {
- pmhctl->disable_hibernation = TRUE;
- /* hibernation will be turned off by isr next time it is entered */
- } else {
- if (pmhctl->disable_hibernation) {
- unsigned long flags;
- spin_lock_irqsave(&mddi_host_spin_lock, flags);
- if (!MDDI_HOST_IS_HCLK_ON)
- MDDI_HOST_ENABLE_HCLK;
- mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
- spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
- pmhctl->disable_hibernation = FALSE;
- }
- }
-}
-
-void mddi_mhctl_remove(mddi_host_type host_idx)
-{
- mddi_host_cntl_type *pmhctl;
-
- pmhctl = &(mhctl[host_idx]);
-
- dma_free_coherent(NULL, MDDI_LLIST_POOL_SIZE, (void *)pmhctl->llist_ptr,
- pmhctl->llist_dma_addr);
-
- dma_free_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
- (void *)pmhctl->rev_data_buf,
- pmhctl->rev_data_dma_addr);
-}